A class is accessable from another?
Ioi Lam
ioi.lam at oracle.com
Sun Jan 3 08:11:27 UTC 2016
The two exceptions that you see here are related to the internal
implementation of the OpenJDK:
Case 1: For JDK 7/8, the exception happened here:
Exception in thread "main" java.lang.IllegalAccessError: tried to access
class java.lang.AbstractStringBuilder from class M1450648087
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
at java.lang.Class.getMethod0(Class.java:2937)
at java.lang.Class.getMethod(Class.java:1771)
at
sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at
sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Note that java.lang.AbstractStringBuilder is an internal, non-public
class and it's inaccessible by class M1450648087.
This exception happens only when the Java launcher looks up the "main"
method. If you put the "throws AbstractStringBuilder" in any other
methods, the JVM will not complain (see
https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf, 4.7.5 The
Exceptions Attribute). So it's quite plausible that the J9 launcher does
something different than the sun.launcher and avoids the exception.
Case 2: In JDK8, the internal class GraphicsPrimitive$TraceReporter was
a subclass of Thread. In JDK9, this class has been changed to "implement
Runnable". Hence it's no longer assignable to Thread. You can read more
about the Verifier in the JVM Spec link posted above.
In both cases, your code is accessing an internal JDK class, so the
behavior may change in different JDK releases, even if there are no spec
changes.
Thanks
- Ioi
On 1/1/16 4:22 AM, 陈雨亭 wrote:
> Hello, everyone. I created a class M1450648087 using soot, while the
> class is
> executable on some JVMs but not on HotSpot releases:
> (1) When the class is tested on IBM's J9 or GIJ, it is executable
> (i.e., "Executed!"
> is printed out);
> (2) When the class is tested using OpenJDK for Java7/8, it says
> "java.lang.IllegalAccessError: tried to access class
> java.lang.AbstractStringBuilder
> from class M1450648087" (the run() method throws
> java.lang.AbstractStringBuilder );
> (3) When the class is tested using OpenJDK for Java9, it says
> "java.lang.VerifyError:
> Bad type on operand stack ...Type
> 'sun/java2d/loops/GraphicsPrimitive$TraceReporter'
> (current frame, stack[1]) is not assignable to 'java/lang/Thread' ".
> (caused by run()...17: invokevirtual #10 // Method
> java/lang/Runtime.addShutdownHook:(Ljava/lang/Thread;)V)
>
> My problem is:
> (1) Where can I find any reference about whether one class is accessable
> from another? Why is the class java.lang.AbstractStringBuilder
> accessable from
> M1450648087 when running on J9 but not accessable
> when on HotSpot releases?
>
> (2) When can one class be assignable to another? I cannot find any
> materials about this. I guess HotSpot for Java9 rejects the assignment
> by taking some new rules. Where can I find these rules?
>
> Yuting
> *************************************************************************************************************
>
> The decompiled code is given as follows.
>
> javap -verbose M1450648087.class
> class M1450648087
> minor version: 0
> major version: 51
> flags: ACC_SUPER
> Constant pool:
> #1 = Utf8 Executed!
> #2 = Utf8 ()V
> #3 = Utf8 main
> #4 = String #1 // Executed!
> #5 = Utf8 java/lang/Object
> #6 = Utf8 java/lang/AbstractStringBuilder
> #7 = Class #5 // java/lang/Object
> #8 = Methodref #24.#35 //
> java/io/PrintStream.println:(Ljava/lang/String;)V
> #9 = Utf8 ()Ljava/lang/Runtime;
> #10 = Methodref #45.#11 //
> java/lang/Runtime.addShutdownHook:(Ljava/lang/Thread;)V
> #11 = NameAndType #47:#26 //
> addShutdownHook:(Ljava/lang/Thread;)V
> #12 = Utf8 java/lang/System
> #13 = Class #6 //
> java/lang/AbstractStringBuilder
> #14 = Class #12 // java/lang/System
> #15 = Utf8 ()Ljava/lang/Object;
> #16 = Utf8 M1450648087
> #17 = Utf8 sun/java2d/loops/GraphicsPrimitive$TraceReporter
> #18 = Methodref #41.#29 //
> sun/java2d/loops/GraphicsPrimitive$TraceReporter.setContextClassLoader:(Ljava/lang/ClassLoader;)V
> #19 = Utf8 run
> #20 = Methodref #41.#23 //
> sun/java2d/loops/GraphicsPrimitive$TraceReporter."<init>":()V
> #21 = Utf8 ([Ljava/lang/String;)V
> #22 = Class #16 // M1450648087
> #23 = NameAndType #30:#2 // "<init>":()V
> #24 = Class #44 // java/io/PrintStream
> #25 = Utf8 Exceptions
> #26 = Utf8 (Ljava/lang/Thread;)V
> #27 = Utf8 SourceFile
> #28 = Utf8 println
> #29 = NameAndType #48:#49 //
> setContextClassLoader:(Ljava/lang/ClassLoader;)V
> #30 = Utf8 <init>
> #31 = NameAndType #32:#46 // out:Ljava/io/PrintStream;
> #32 = Utf8 out
> #33 = NameAndType #38:#9 //
> getRuntime:()Ljava/lang/Runtime;
> #34 = Methodref #7.#23 // java/lang/Object."<init>":()V
> #35 = NameAndType #28:#42 // println:(Ljava/lang/String;)V
> #36 = Methodref #45.#33 //
> java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
> #37 = Utf8 Jasmin
> #38 = Utf8 getRuntime
> #39 = Utf8 java/lang/Runtime
> #40 = Fieldref #14.#31 //
> java/lang/System.out:Ljava/io/PrintStream;
> #41 = Class #17 //
> sun/java2d/loops/GraphicsPrimitive$TraceReporter
> #42 = Utf8 (Ljava/lang/String;)V
> #43 = Utf8 Code
> #44 = Utf8 java/io/PrintStream
> #45 = Class #39 // java/lang/Runtime
> #46 = Utf8 Ljava/io/PrintStream;
> #47 = Utf8 addShutdownHook
> #48 = Utf8 setContextClassLoader
> #49 = Utf8 (Ljava/lang/ClassLoader;)V
> {
> M1450648087();
> descriptor: ()V
> flags:
> Code:
> stack=1, locals=1, args_size=1
> 0: aload_0
> 1: invokespecial #34 // Method
> java/lang/Object."<init>":()V
> 4: return
>
> public java.lang.Object run() throws java.lang.AbstractStringBuilder;
> descriptor: ()Ljava/lang/Object;
> flags: ACC_PUBLIC
> Code:
> stack=2, locals=1, args_size=1
> 0: new #41 // class
> sun/java2d/loops/GraphicsPrimitive$TraceReporter
> 3: dup
> 4: invokespecial #20 // Method
> sun/java2d/loops/GraphicsPrimitive$TraceReporter."<init>":()V
> 7: astore_0
> 8: aload_0
> 9: aconst_null
> 10: invokevirtual #18 // Method
> sun/java2d/loops/GraphicsPrimitive$TraceReporter.setContextClassLoader:(Ljava/lang/ClassLoader;)V
> 13: invokestatic #36 // Method
> java/lang/Runtime.getRuntime:()Ljava/lang/Runtime;
> 16: aload_0
> 17: invokevirtual #10 // Method
> java/lang/Runtime.addShutdownHook:(Ljava/lang/Thread;)V
> 20: aconst_null
> 21: areturn
> Exceptions:
> throws java.lang.AbstractStringBuilder
>
> public static void main(java.lang.String[]);
> descriptor: ([Ljava/lang/String;)V
> flags: ACC_PUBLIC, ACC_STATIC
> Code:
> stack=2, locals=1, args_size=1
> 0: getstatic #40 // Field
> java/lang/System.out:Ljava/io/PrintStream;
> 3: ldc #4 // String Executed!
> 5: invokevirtual #8 // Method
> java/io/PrintStream.println:(Ljava/lang/String;)V
> 8: return
> }
More information about the hotspot-runtime-dev
mailing list