When a TypeElement that represents an anonymous innerclass is load from a pre-1.5 classfile, its getNestingKind() returns TOP_LEVEL rather than ANONYMOUS.
The problem can be reproduced using the folliwng test (a patch against http://hg.openjdk.java.net/jdk7/tl/langtools/rev/508c01999047):
-------------------------------------------------------------------------------------------
diff --git a/test/tools/javac/AnonymousClassLoading.java b/test/tools/javac/AnonymousClassLoading.java
new file mode 100644
--- /dev/null
+++ b/test/tools/javac/AnonymousClassLoading.java
@@ -0,0 +1,115 @@
+/*
+ * @test
+ */
+import com.sun.source.util.JavacTask;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Set;
+import javax.lang.model.element.NestingKind;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementScanner6;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+public class AnonymousClassLoading {
+
+ static class MyFileObject extends SimpleJavaFileObject {
+ private String text;
+ public MyFileObject(String text) {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ this.text = text;
+ }
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return text;
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ assert tool != null;
+
+ String code = "public class Test {}";
+
+ JavacTask ct = (JavacTask)tool.getTask(null, new JFM(tool.getStandardFileManager(null, null, null)), null, Arrays.asList("-bootclasspath", bootPath, "-Xjcov"), null, Arrays.asList(new MyFileObject(code)));
+
+ ct.analyze();
+
+ PackageElement pack = ct.getElements().getPackageElement("");
+
+ new ElementScanner6<Void, Void>() {
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ if (!e.getQualifiedName().contentEquals("Main") && !e.getQualifiedName().contentEquals("Test")) {
+ if (NestingKind.ANONYMOUS != e.getNestingKind()) {
+ throw new IllegalStateException(e.getNestingKind().name());
+ }
+ }
+
+ return super.visitType(e, p);
+ }
+ }.visit(pack);
+ }
+
+ private static final class JFM extends ForwardingJavaFileManager<JavaFileManager> {
+
+ public JFM(JavaFileManager delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
+ if (StandardLocation.CLASS_PATH == location && "".equals(packageName) && kinds.contains(Kind.CLASS)) {
+ try {
+ return Arrays.<JavaFileObject>asList(ClassJFO.create("Main"), ClassJFO.create("Main$1"));
+ } catch (URISyntaxException ex) {
+ throw new IOException(ex);
+ }
+ }
+
+ return super.list(location, packageName, kinds, recurse);
+ }
+
+ @Override
+ public String inferBinaryName(Location location, JavaFileObject file) {
+ if (file instanceof ClassJFO) {
+ return ((ClassJFO) file).binaryName;
+ }
+
+ return super.inferBinaryName(location, file);
+ }
+
+ }
+
+ private static final class ClassJFO extends SimpleJavaFileObject {
+
+ private String binaryName;
+
+ public ClassJFO(URI uri, String binaryName) {
+ super(uri, Kind.CLASS);
+ this.binaryName = binaryName;
+ }
+
+ public static final ClassJFO create(String name) throws URISyntaxException {
+ return new ClassJFO(AnonymousClassLoading.class.getResource(name + ".class").toURI(), name);
+ }
+
+ @Override
+ public InputStream openInputStream() throws IOException {
+ return uri.toURL().openStream();
+ }
+
+ }
+}
diff --git a/test/tools/javac/Main$1.class b/test/tools/javac/Main$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..abfb2db94be9827560b6a808f53e35c9bb4a1c50
GIT binary patch
literal 289
zc${U9J4?hs6ot=C+`Nn=rn3;X*g`E5wila#Aou_k`$=|KCd3=a!~bQqVBrt&M~Qc`
zpoPWUJM+!qob&bl@d+SD7QsdA<H$$q<Cx%G8aCq<!96>FAsm$5MiY`-!}@-Dt#tpa
zs#b{GPfUoOx~Z@AwXrC?Q-<?Ky{Q-rc;aQjYE1wkzG2pV*{WgC10l7tqE);t9;!yy
zBO&`kj}x<v!4i)2lNwUikt4S9^5u3an=HB5f!<*w0-4?($_#&{C-X1<%RKRnX6HjB
LvLm531qglsxi2l^
diff --git a/test/tools/javac/Main.class b/test/tools/javac/Main.class
new file mode 100644
index 0000000000000000000000000000000000000000..d84c2be3bd35fae55e45a76a2a2ad75972d7cee7
GIT binary patch
literal 316
zc$`I0T}uK%6g_uc_p2?nq&FXe0_#EPx$s300<8z5ke+63kdbwS-L?PKlaSC4@JEIB
z4uLap@65U9W0?Kl&o6);+6n473(-j6Nk0#9K?oj=HPwJn>)yT*{Negj6B=V<_48(x
z>EcyoIV1i`8B4hAevFsuOZ9VQ7yW5f7`u27VKQBBin$&cA;%LY_k@=sK*%WqT;CHw
zNT00L#V}W8sY^DVIOFEg^(9;Cd4((Z{9sugtJsEX#J3K2HbVVw3;Kpw##{pj$~nQw
iKlR2*fp`aRwngpzNS99lCq%qGq%P$YEjJ-I1EK@&S2Gy^
-------------------------------------------------------------------------------------------
The problem can be reproduced using the folliwng test (a patch against http://hg.openjdk.java.net/jdk7/tl/langtools/rev/508c01999047):
-------------------------------------------------------------------------------------------
diff --git a/test/tools/javac/AnonymousClassLoading.java b/test/tools/javac/AnonymousClassLoading.java
new file mode 100644
--- /dev/null
+++ b/test/tools/javac/AnonymousClassLoading.java
@@ -0,0 +1,115 @@
+/*
+ * @test
+ */
+import com.sun.source.util.JavacTask;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Set;
+import javax.lang.model.element.NestingKind;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementScanner6;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+public class AnonymousClassLoading {
+
+ static class MyFileObject extends SimpleJavaFileObject {
+ private String text;
+ public MyFileObject(String text) {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ this.text = text;
+ }
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return text;
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+ final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ assert tool != null;
+
+ String code = "public class Test {}";
+
+ JavacTask ct = (JavacTask)tool.getTask(null, new JFM(tool.getStandardFileManager(null, null, null)), null, Arrays.asList("-bootclasspath", bootPath, "-Xjcov"), null, Arrays.asList(new MyFileObject(code)));
+
+ ct.analyze();
+
+ PackageElement pack = ct.getElements().getPackageElement("");
+
+ new ElementScanner6<Void, Void>() {
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ if (!e.getQualifiedName().contentEquals("Main") && !e.getQualifiedName().contentEquals("Test")) {
+ if (NestingKind.ANONYMOUS != e.getNestingKind()) {
+ throw new IllegalStateException(e.getNestingKind().name());
+ }
+ }
+
+ return super.visitType(e, p);
+ }
+ }.visit(pack);
+ }
+
+ private static final class JFM extends ForwardingJavaFileManager<JavaFileManager> {
+
+ public JFM(JavaFileManager delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
+ if (StandardLocation.CLASS_PATH == location && "".equals(packageName) && kinds.contains(Kind.CLASS)) {
+ try {
+ return Arrays.<JavaFileObject>asList(ClassJFO.create("Main"), ClassJFO.create("Main$1"));
+ } catch (URISyntaxException ex) {
+ throw new IOException(ex);
+ }
+ }
+
+ return super.list(location, packageName, kinds, recurse);
+ }
+
+ @Override
+ public String inferBinaryName(Location location, JavaFileObject file) {
+ if (file instanceof ClassJFO) {
+ return ((ClassJFO) file).binaryName;
+ }
+
+ return super.inferBinaryName(location, file);
+ }
+
+ }
+
+ private static final class ClassJFO extends SimpleJavaFileObject {
+
+ private String binaryName;
+
+ public ClassJFO(URI uri, String binaryName) {
+ super(uri, Kind.CLASS);
+ this.binaryName = binaryName;
+ }
+
+ public static final ClassJFO create(String name) throws URISyntaxException {
+ return new ClassJFO(AnonymousClassLoading.class.getResource(name + ".class").toURI(), name);
+ }
+
+ @Override
+ public InputStream openInputStream() throws IOException {
+ return uri.toURL().openStream();
+ }
+
+ }
+}
diff --git a/test/tools/javac/Main$1.class b/test/tools/javac/Main$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..abfb2db94be9827560b6a808f53e35c9bb4a1c50
GIT binary patch
literal 289
zc${U9J4?hs6ot=C+`Nn=rn3;X*g`E5wila#Aou_k`$=|KCd3=a!~bQqVBrt&M~Qc`
zpoPWUJM+!qob&bl@d+SD7QsdA<H$$q<Cx%G8aCq<!96>FAsm$5MiY`-!}@-Dt#tpa
zs#b{GPfUoOx~Z@AwXrC?Q-<?Ky{Q-rc;aQjYE1wkzG2pV*{WgC10l7tqE);t9;!yy
zBO&`kj}x<v!4i)2lNwUikt4S9^5u3an=HB5f!<*w0-4?($_#&{C-X1<%RKRnX6HjB
LvLm531qglsxi2l^
diff --git a/test/tools/javac/Main.class b/test/tools/javac/Main.class
new file mode 100644
index 0000000000000000000000000000000000000000..d84c2be3bd35fae55e45a76a2a2ad75972d7cee7
GIT binary patch
literal 316
zc$`I0T}uK%6g_uc_p2?nq&FXe0_#EPx$s300<8z5ke+63kdbwS-L?PKlaSC4@JEIB
z4uLap@65U9W0?Kl&o6);+6n473(-j6Nk0#9K?oj=HPwJn>)yT*{Negj6B=V<_48(x
z>EcyoIV1i`8B4hAevFsuOZ9VQ7yW5f7`u27VKQBBin$&cA;%LY_k@=sK*%WqT;CHw
zNT00L#V}W8sY^DVIOFEg^(9;Cd4((Z{9sugtJsEX#J3K2HbVVw3;Kpw##{pj$~nQw
iKlR2*fp`aRwngpzNS99lCq%qGq%P$YEjJ-I1EK@&S2Gy^
-------------------------------------------------------------------------------------------
- relates to
-
JDK-8012119 javac is generating the InnerClasses attribute in cases where it shouldn't
- Open