-
Bug
-
Resolution: Not an Issue
-
P2
-
None
-
8
-
b132
The issue has been encountered while considering the following situation.
1. Initially 3 classes were compiled:
/* Test.java */
public class Test {
public static void main(String argv[]) {
try {
Class<?> methodInvokeClass = Class.forName("MethodInvoker");
} catch (Throwable e) {
e.printStackTrace();
}
}
}
/* MethodInvoker.java */
import anotherpkg.*;
public class MethodInvoker extends MethodSupplier {
}
/* anotherpkg/MethodSupplier.java */
package anotherpkg;
public class MethodSupplier {
public void m() {
System.out.println("good");
}
}
2. Then MethodSupplier's access modifier was change to package-private and anotherpkg/MethodSupplier.java was recompiled
/* anotherpkg/MethodSupplier.java */
package anotherpkg;
class MethodSupplier {
public void m() {
System.out.println("good");
}
}
3. While running Test.main(), Class.forName() throws IllegalAccessError.
As far as we understand, it should not be thrown due to the following assertions:
1. API javadoc of Class.forName (http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-boolean-java.lang.ClassLoader-) says:
"Note that this method throws errors related to loading, linking or initializing as specified in Sections 12.2, 12.3 and 12.4 of The Java Language Specification".
2. Java Language Specification, section 12.3.3 (https://baloo.ru.oracle.com/jenkins/job/jck8a-lang/lastSuccessfulBuild/artifact/build/out/htmlout/jls-12.html#jls-12.3.3-120) mentions the following:
"If an error occurs during resolution, then an error will be thrown... This error may be thrown at any point in the program that uses a symbolic reference to the type, directly or indirectly"
3. JVMS (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3) says the similar thing:
"If an error occurs during resolution of a symbolic reference, then an instance of IncompatibleClassChangeError (or a subclass) must be thrown at a point in the program that (directly or indirectly) uses the symbolic reference."
According to our understanding Class.forName invocation couldn't be considered as a "point in the program that uses a symbolic reference to the type, directly or indirectly".
1. Initially 3 classes were compiled:
/* Test.java */
public class Test {
public static void main(String argv[]) {
try {
Class<?> methodInvokeClass = Class.forName("MethodInvoker");
} catch (Throwable e) {
e.printStackTrace();
}
}
}
/* MethodInvoker.java */
import anotherpkg.*;
public class MethodInvoker extends MethodSupplier {
}
/* anotherpkg/MethodSupplier.java */
package anotherpkg;
public class MethodSupplier {
public void m() {
System.out.println("good");
}
}
2. Then MethodSupplier's access modifier was change to package-private and anotherpkg/MethodSupplier.java was recompiled
/* anotherpkg/MethodSupplier.java */
package anotherpkg;
class MethodSupplier {
public void m() {
System.out.println("good");
}
}
3. While running Test.main(), Class.forName() throws IllegalAccessError.
As far as we understand, it should not be thrown due to the following assertions:
1. API javadoc of Class.forName (http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-boolean-java.lang.ClassLoader-) says:
"Note that this method throws errors related to loading, linking or initializing as specified in Sections 12.2, 12.3 and 12.4 of The Java Language Specification".
2. Java Language Specification, section 12.3.3 (https://baloo.ru.oracle.com/jenkins/job/jck8a-lang/lastSuccessfulBuild/artifact/build/out/htmlout/jls-12.html#jls-12.3.3-120) mentions the following:
"If an error occurs during resolution, then an error will be thrown... This error may be thrown at any point in the program that uses a symbolic reference to the type, directly or indirectly"
3. JVMS (http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3) says the similar thing:
"If an error occurs during resolution of a symbolic reference, then an instance of IncompatibleClassChangeError (or a subclass) must be thrown at a point in the program that (directly or indirectly) uses the symbolic reference."
According to our understanding Class.forName invocation couldn't be considered as a "point in the program that uses a symbolic reference to the type, directly or indirectly".