8314621: ClassNotFoundException due to lambda reference to elided anonymous inner class
Reviewed-by: jlahoda
This commit is contained in:
parent
52e2878cff
commit
d6aa7c8ba0
@ -1196,6 +1196,18 @@ public class Lower extends TreeTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean noClassDefIn(JCTree tree) {
|
||||
var scanner = new TreeScanner() {
|
||||
boolean noClassDef = true;
|
||||
@Override
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
noClassDef = false;
|
||||
}
|
||||
};
|
||||
scanner.scan(tree);
|
||||
return scanner.noClassDef;
|
||||
}
|
||||
|
||||
private void addPrunedInfo(JCTree tree) {
|
||||
List<JCTree> infoList = prunedTree.get(currentClass);
|
||||
infoList = (infoList == null) ? List.of(tree) : infoList.prepend(tree);
|
||||
@ -3030,10 +3042,10 @@ public class Lower extends TreeTranslator {
|
||||
@Override
|
||||
public void visitConditional(JCConditional tree) {
|
||||
JCTree cond = tree.cond = translate(tree.cond, syms.booleanType);
|
||||
if (isTrue(cond)) {
|
||||
if (isTrue(cond) && noClassDefIn(tree.falsepart)) {
|
||||
result = convert(translate(tree.truepart, tree.type), tree.type);
|
||||
addPrunedInfo(cond);
|
||||
} else if (isFalse(cond)) {
|
||||
} else if (isFalse(cond) && noClassDefIn(tree.truepart)) {
|
||||
result = convert(translate(tree.falsepart, tree.type), tree.type);
|
||||
addPrunedInfo(cond);
|
||||
} else {
|
||||
@ -3057,10 +3069,10 @@ public class Lower extends TreeTranslator {
|
||||
*/
|
||||
public void visitIf(JCIf tree) {
|
||||
JCTree cond = tree.cond = translate(tree.cond, syms.booleanType);
|
||||
if (isTrue(cond)) {
|
||||
if (isTrue(cond) && noClassDefIn(tree.elsepart)) {
|
||||
result = translate(tree.thenpart);
|
||||
addPrunedInfo(cond);
|
||||
} else if (isFalse(cond)) {
|
||||
} else if (isFalse(cond) && noClassDefIn(tree.thenpart)) {
|
||||
if (tree.elsepart != null) {
|
||||
result = translate(tree.elsepart);
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -47,6 +47,7 @@ public class GraphicalInstallerTest {
|
||||
}
|
||||
|
||||
check(classes,
|
||||
"GraphicalInstaller$1.class",
|
||||
"GraphicalInstaller$1X$1.class",
|
||||
"GraphicalInstaller$1X.class",
|
||||
"GraphicalInstaller$BackgroundInstaller.class",
|
||||
|
@ -70,12 +70,15 @@ public class T6917288 {
|
||||
}
|
||||
|
||||
switch (k) {
|
||||
case NONE:
|
||||
check(classesDir, "Test.class", "Test$Inner.class");
|
||||
break;
|
||||
case ALWAYS:
|
||||
case TRUE:
|
||||
check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class");
|
||||
break;
|
||||
default:
|
||||
check(classesDir, "Test.class", "Test$Inner.class");
|
||||
check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7199823
|
||||
* @summary javac generates inner class that can't be verified
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* @run main InnerClassCannotBeVerified
|
||||
*/
|
||||
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.util.Arrays;
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.net.URI;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.ToolProvider;
|
||||
import javax.tools.JavaCompiler;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import jdk.internal.classfile.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class InnerClassCannotBeVerified {
|
||||
|
||||
enum CompilationKind {
|
||||
PRE_NESTMATES("-source", "10", "-target", "10"),
|
||||
POST_NESTMATES();
|
||||
|
||||
String[] opts;
|
||||
|
||||
CompilationKind(String... opts) {
|
||||
this.opts = opts;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String errorMessage =
|
||||
"Compile error while compiling the following source:\n";
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new InnerClassCannotBeVerified().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
for (CompilationKind ck : CompilationKind.values()) {
|
||||
File file = new File("Test$1.class");
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
||||
JavaSource source = new JavaSource();
|
||||
JavacTask ct = (JavacTask)comp.getTask(null, null, null,
|
||||
Arrays.asList(ck.opts), null, Arrays.asList(source));
|
||||
try {
|
||||
if (!ct.call()) {
|
||||
throw new AssertionError(errorMessage +
|
||||
source.getCharContent(true));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
throw new AssertionError(errorMessage +
|
||||
source.getCharContent(true));
|
||||
}
|
||||
check(ck);
|
||||
}
|
||||
}
|
||||
|
||||
private void check(CompilationKind ck) throws IOException {
|
||||
try {
|
||||
File file = new File("Test$1.class");
|
||||
ClassModel classFile = Classfile.of().parse(file.toPath());
|
||||
if (ck == CompilationKind.POST_NESTMATES) {
|
||||
throw new AssertionError("Unexpected constructor tag class!");
|
||||
}
|
||||
boolean inheritsFromObject =
|
||||
classFile.superclass().orElseThrow().asInternalName().equals("java/lang/Object");
|
||||
boolean implementsNoInterface = classFile.interfaces().size() == 0;
|
||||
boolean noMethods = classFile.methods().size() == 0;
|
||||
if (!(inheritsFromObject &&
|
||||
implementsNoInterface &&
|
||||
noMethods)) {
|
||||
throw new AssertionError("The inner classes reused as " +
|
||||
"access constructor tag for this code must be empty");
|
||||
}
|
||||
} catch (NoSuchFileException ex) {
|
||||
if (ck == CompilationKind.PRE_NESTMATES) {
|
||||
throw new AssertionError("Constructor tag class missing!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JavaSource extends SimpleJavaFileObject {
|
||||
|
||||
String internalSource =
|
||||
"public class Test {\n" +
|
||||
" private static class Foo {}\n" +
|
||||
" public static void main(String[] args){ \n" +
|
||||
" new Foo();\n" +
|
||||
" if(false) {\n" +
|
||||
" new Runnable() {\n" +
|
||||
" @Override\n" +
|
||||
" public void run() {\n" +
|
||||
" System.out.println();\n" +
|
||||
" }\n" +
|
||||
" }.run();\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
public JavaSource() {
|
||||
super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return internalSource;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8314621
|
||||
* @summary ClassNotFoundException due to lambda reference to elided anonymous inner class
|
||||
*/
|
||||
|
||||
public class ClassNotFoundExceptionDueToPrunedCodeTest {
|
||||
public static void main(String... args) {
|
||||
var o1 = false ? new Object() {} : null;
|
||||
Runnable r = () -> {
|
||||
System.out.println(o1 == o1);
|
||||
};
|
||||
r.run();
|
||||
|
||||
var o2 = true ? null : new Object() {};
|
||||
r = () -> {
|
||||
System.out.println(o2 == o2);
|
||||
};
|
||||
r.run();
|
||||
|
||||
var o3 = switch (0) { default -> { if (false) yield new Object() { }; else yield null; } };
|
||||
r = () -> System.out.println(o3);
|
||||
r.run();
|
||||
|
||||
var o4 = switch (0) { default -> { if (true) yield null; else yield new Object() { }; } };
|
||||
r = () -> System.out.println(o4);
|
||||
r.run();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user