FULL PRODUCT VERSION :
java version "1.8.0_60-ea"
Java(TM) SE Runtime Environment (build 1.8.0_60-ea-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b12, mixed mode)
Already broken in 1.7. Works in IBM SDK.
A DESCRIPTION OF THE PROBLEM :
The Oracle JRE depends on undocumented ordering of the InnerClasses attribute entries. In certain cases, Class.getDeclaringClass0() throws a wrong IllegalAccessError.
Javac seems to produce .class files that don't trigger this bug.
Class files produced by the Eclipse compiler for Java (ecj) can trigger the bug, since ecj orders InnerClasses entries alphabetically.
Here's the javap -v of an affected .class file:
InnerClasses:
static #45= #41 of #43; //Builder=class com/g/Base$Builder of class com/g/Base
public static final #46= #24 of #1; //Foo=class com/n/Buggered$Foo of class com/n/Buggered
Note that another entry appears before the com/n/Buggered$Foo.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Did not try
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Did not try
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- compile the given source with ecj (simplest way is to install the Eclipse SDK from [1], and then past the complete source into the Package Explorer)
- run class com.n.Buggered
Original issues reported against Eclipse JDT:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=445231
https://bugs.eclipse.org/bugs/show_bug.cgi?id=466675
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: no output
Actual: IAE
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IllegalAccessError: tried to access class com.g.Base from class com.n.Buggered
at java.lang.Class.getDeclaringClass0(Native Method)
at java.lang.Class.getDeclaringClass(Class.java:1235)
at java.lang.Class.getEnclosingClass(Class.java:1277)
at java.lang.Class.getSimpleBinaryName(Class.java:1443)
at java.lang.Class.getSimpleName(Class.java:1309)
at java.lang.Class.isAnonymousClass(Class.java:1411)
at com.n.Buggered.main(Buggered.java:10)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.g;
class Base {
static class Builder { }
}
public final class Child extends Base {
public Builder setJobName() {
return null;
}
}
package com.n;
import com.g.Child;
public final class Buggered {
public static final class Foo { }
void unused() {
new Child().setJobName();
}
public static void main(String[] args) {
Class<?> clazz = Buggered.Foo.class;
clazz.isAnonymousClass();
}
}
---------- END SOURCE ----------
java version "1.8.0_60-ea"
Java(TM) SE Runtime Environment (build 1.8.0_60-ea-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b12, mixed mode)
Already broken in 1.7. Works in IBM SDK.
A DESCRIPTION OF THE PROBLEM :
The Oracle JRE depends on undocumented ordering of the InnerClasses attribute entries. In certain cases, Class.getDeclaringClass0() throws a wrong IllegalAccessError.
Javac seems to produce .class files that don't trigger this bug.
Class files produced by the Eclipse compiler for Java (ecj) can trigger the bug, since ecj orders InnerClasses entries alphabetically.
Here's the javap -v of an affected .class file:
InnerClasses:
static #45= #41 of #43; //Builder=class com/g/Base$Builder of class com/g/Base
public static final #46= #24 of #1; //Foo=class com/n/Buggered$Foo of class com/n/Buggered
Note that another entry appears before the com/n/Buggered$Foo.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Did not try
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Did not try
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- compile the given source with ecj (simplest way is to install the Eclipse SDK from [1], and then past the complete source into the Package Explorer)
- run class com.n.Buggered
Original issues reported against Eclipse JDT:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=445231
https://bugs.eclipse.org/bugs/show_bug.cgi?id=466675
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: no output
Actual: IAE
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IllegalAccessError: tried to access class com.g.Base from class com.n.Buggered
at java.lang.Class.getDeclaringClass0(Native Method)
at java.lang.Class.getDeclaringClass(Class.java:1235)
at java.lang.Class.getEnclosingClass(Class.java:1277)
at java.lang.Class.getSimpleBinaryName(Class.java:1443)
at java.lang.Class.getSimpleName(Class.java:1309)
at java.lang.Class.isAnonymousClass(Class.java:1411)
at com.n.Buggered.main(Buggered.java:10)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.g;
class Base {
static class Builder { }
}
public final class Child extends Base {
public Builder setJobName() {
return null;
}
}
package com.n;
import com.g.Child;
public final class Buggered {
public static final class Foo { }
void unused() {
new Child().setJobName();
}
public static void main(String[] args) {
Class<?> clazz = Buggered.Foo.class;
clazz.isAnonymousClass();
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8212056 Can code that checks classes in InnerClasses attributes be simplified?
-
- Closed
-