RFR: 8038468: java/lang/instrument/ParallelTransformerLoader.sh fails with ClassCircularityError

serguei.spitsyn at oracle.com serguei.spitsyn at oracle.com
Sat Nov 1 09:59:39 UTC 2014


On 10/31/14 4:55 PM, Yumin Qi wrote:
> Karen,
>
>   Thanks for your detail message for debugging. Yes, from my 
> debugging, the exception did happen in TestThread other than main 
> thread. I have no idea why in the end the exception was reported in 
> main thread.
>
>    You mention
>
> So that change to the test would be:
>     in TestTransformer:
>        if (loader != null) {
>            if (tName.equals("TestThread")) {
>            {
>               loadClasses(3);
>            }
>         }
>         return null;
>      }
>
> The loader is the one defined in the test case, right?

Not sure, I understand your question correctly.

If thread is the TestThread then most likely the answer is "Yes".
This one is expected:
                 sClassLoader = new URLClassLoader(new URL[] {sURL});

The class loading for TestThread has to happen in the loadClasses(2).
I wonder if we ever observe any other loader for the TestThread.

The question is because the TestThread is pretty simple:

         private static class TestThread extends Thread {
                 private final int fIndex;
                 public TestThread(int index) {         <== it is called 
with index = 2
                      super("TestThread");
                      fIndex = index;
                 }
                 public void  run() {  loadClasses(fIndex); }
         }

Thanks,
Serguei


> The system class loader is never null.
> I will try this change, let's see if it can work it out.
>
> Thanks
> Yumin
>
> On 10/31/2014 3:29 PM, Karen Kinnear wrote:
>> Yumin,
>>
>>  From your earlier exception stack trace (many thanks) you reported:
>>
>> Exception in thread "main" java.lang.ClassCircularityError:  (no - I don't know why this is in thread "main")
>> sun/misc/URLClassPath$JarLoader$2
>> at sun.misc.URLClassPath$JarLoader.checkResource(URLClassPath.java:771)
>> at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:843)
>> at sun.misc.URLClassPath.getResource(URLClassPath.java:199)
>> at java.net.URLClassLoader$1.run(URLClassLoader.java:364)
>> at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
>> at java.security.AccessController.doPrivileged(Native Method)
>> at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426)
>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359)
>> at java.lang.Class.forName0(Native Method)
>> at java.lang.Class.forName(Class.java:340)
>> at ParallelTransformerLoaderApp.loadClasses(ParallelTransformerLoaderApp.java:83)
>> at ParallelTransformerLoaderApp.main(ParallelTransformerLoaderApp.java:45)
>>
>>
>> So I ran  with -XX:AbortVMOnException=java.lang.ClassCircularityError -XX:+ShowMessageBoxOnError to get
>> a log file and stack trace. See my instructions below on how to do that.
>>
>> I did this, attached a debugger, which didn't help enough since I needed to see the java stack frames,
>>   and got an hs_err_log also, so the stack traces came from the error log.
>>
>> The stack trace was on Thread 2, which in the hs_err_log was TestThread (which makes sense for what the test logic says).
>> See later in email for stack traces from Thread 2.
>>
>> Summary of stack trace:
>>
>> TestThread:
>>    loadClasses(#) -> forName(TestClass#, URLClassLoader)
>>      vm calls out to URLClassLoader.loadClass(String) which is inherited from java.lang.ClassLoader.loadClass(String)
>>      ... calls java.net.URLClassLoader.findClass(...) which calls
>>        DoPrivileged  java.net.URLClassLoader$1.run which calls
>>           sun.misc.URLClassPath.getResource(name, false)  which calls
>>               sun.misc.URLClassPath$JarLoader.getResource which calls
>>                   sun.misc.URLClassPath$JarLoader.checkResource which tries to call sun.misc.URLClassPath$JarLoader$2
>>     - and then the transformer jumps in with loadClasses(# (which we know is 3) and walks the same logic which tries to load sun.misc.URLClassPath$JarLoader$2 again
>>
>> Note that in the placeholder table information that Yumin printed, the circularity error is on sun.misc.URLClassPath$JarLoader$2 with the null == boot loader, which
>> makes sense -- that is the appropriate defining loader, and therefore the one the CFLH would intercept during the defineClass phase.
>>
>> In the sun.misc.URLClassPath.java file, in the class JarLoader, in the method checkResource
>> ... return new Resource() { ... }
>> -- I do not know why that generates sun.misc.URLClassPath$JarLoader$1, $2 and $3 at build time or when that was added.
>> I would guess that is when the bug started happening.
>>
>> When I have a successful run, sun.misc.URLClassPath$JarLoader$2 loads before any TestClass1 loads.
>>
>> My belief is that the point of the test is to test parallel class loading for URL class loaders.
>> I don't think the point is to test the bootstrap class loader, nor to test bootstrapping - i.e. running the agent before
>> we have loaded sufficient classes to allow loading URLClassLoader classes.
>>
>> What I suggested to Yumin that he try would be to change the test to NOT intercept boot loader loads, so that sun.misc.URLClassPath$JarLoader$#
>> can load which will in turn allow classes loaded by a URLClassLoader subclass to load.
>>
>> So that change to the test would be:
>>     in TestTransformer:
>>        if (loader != null) {
>>            if (tName.equals("TestThread")) {
>>            {
>>               loadClasses(3);
>>            }
>>         }
>>         return null;
>>      }
>> // I also suspect with that change, we can remove the sleep loop
>> Note: there was a printed message which said that the Thread "Signal Dispatcher" has called transform(), which I
>> ignored, however it is good that we don't call loadClass on that thread  - which is part of what the sleep loop does -
>> but that would be handled by the boot loader screening above
>>
>> Alternatively we can preload the URLClassPath classes, but I don't think we want to do that, or
>> we can have the agent explicitly screen on a variety of jdk bootstrapping classes. But I think the cleaner
>> solution is to screen on the boot loader.
>>
>> Does that make any sense to others?
>>
>> thanks,
>> Karen
>>
>> p.s. How to run with hotspot flags (jtreg has a -show:rerun option, but with a shell script in the test, this is more complex, so
>> the following should be easier):
>>
>> So what I did was run the test once for it to pass (not your script, but just once with jtreg) so that it generated
>> the $DST/work directory.
>> I then created a rerun.csh script - attached - you can modify for your own $DST directory.
>> I used it to be able to quickly rerun the test without the jtreg framework and compile time etc. but mostly
>> to be able to actually add hotspot command-line flags.
>>
>>
>>
>> p.p.s. details from the error log (let me know if you want me to attach the error log to the bug report)
>>
>> note: error log shows last 10 events including:
>> Event: 0.928 loading class sun/misc/URLClassPath$JarLoader$2
>> Event: 0.928 loading class TestClass3
>> Event: 0.929 loading class TestClass3 done
>> Event: 0.929 loading class java/lang/ClassCircularityError
>> Event: 0.929 loading class java/lang/ClassCircularityError done
>>
>> TestThread
>>
>> java frames:
>>
>> j  sun.misc.URLClassPath$JarLoader.checkResource(Ljava/lang/String;ZLjava/util/jar/JarEntry;)Lsun/misc/Resource;+42
>> j  sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+54
>> j  sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+53
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Class;+26
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Object;+1
>> v  ~StubRoutines::call_stub
>> j  java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;+0
>> j  java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;+13
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;+70
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
>> v  ~StubRoutines::call_stub
>> j  java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+0
>> j  java.lang.Class.forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;+49
>> j  ParallelTransformerLoaderAgent$TestTransformer.loadClasses(I)V+25
>> j  ParallelTransformerLoaderAgent$TestTransformer.transform(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[B)[B+81
>> j  sun.instrument.TransformerManager.transform(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[B)[B+50
>> j  sun.instrument.InstrumentationImpl.transform(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[BZ)[B+34
>> v  ~StubRoutines::call_stub
>> j  sun.misc.URLClassPath$JarLoader.checkResource(Ljava/lang/String;ZLjava/util/jar/JarEntry;)Lsun/misc/Resource;+42
>> j  sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+54
>> j  sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+53
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Class;+26
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Object;+1
>> v  ~StubRoutines::call_stub
>> j  java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;+0
>> j  java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;+13
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;+70
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
>> v  ~StubRoutines::call_stub
>> j  java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+0
>> j  java.lang.Class.forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;+49
>> j  ParallelTransformerLoaderApp.loadClasses(I)V+25
>> j  ParallelTransformerLoaderApp$TestThread.run()V+4
>> v  ~StubRoutines::call_stub
>>
>>
>>    
>>
>> detailed frames:
>>
>> V  [libjvm.so+0x760f5a]  Exceptions::_throw_msg(Thread*, char const*, int, Symbol*, char const*)+0x7c
>> V  [libjvm.so+0xce005c]  SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*)+0x7d8
>> V  [libjvm.so+0xcde9e5]  SystemDictionary::resolve_or_null(Symbol*, Handle, Handle, Thread*)+0x26d
>> V  [libjvm.so+0xcde435]  SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*)+0x39
>> V  [libjvm.so+0x690fbc]  ConstantPool::klass_at_impl(constantPoolHandle, int, Thread*)+0x3cc
>> V  [libjvm.so+0x5398cb]  ConstantPool::klass_at(int, Thread*)+0x55
>> V  [libjvm.so+0x8b1f3c]  InterpreterRuntime::_new(JavaThread*, ConstantPool*, int)+0x14a
>> j  sun.misc.URLClassPath$JarLoader.checkResource(Ljava/lang/String;ZLjava/util/jar/JarEntry;)Lsun/misc/Resource;+42
>> j  sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+54
>> j  sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+53
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Class;+26
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Object;+1
>> v  ~StubRoutines::call_stub
>> V  [libjvm.so+0x8c3060]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x6b2
>> V  [libjvm.so+0xba06bc]  os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x3a
>> V  [libjvm.so+0x8c29a7]  JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+0x7d
>> V  [libjvm.so+0x972a80]  JVM_DoPrivileged+0x63d
>> j  java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;+0
>> j  java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;+13
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;+70
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;+3
>> v  ~StubRoutines::call_stub
>> V  [libjvm.so+0x8c3060]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x6b2
>> V  [libjvm.so+0xba06bc]  os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x3a
>> V  [libjvm.so+0x8c29a7]  JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+0x7d
>> V  [libjvm.so+0x8c1ec7]  JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x1cb
>> V  [libjvm.so+0x8c2086]  JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Handle, Thread*)+0xb0
>> V  [libjvm.so+0xce2096]  SystemDictionary::load_instance_class(Symbol*, Handle, Thread*)+0x4ea
>> V  [libjvm.so+0xce00a8]  SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*)+0x824
>> V  [libjvm.so+0xcde9e5]  SystemDictionary::resolve_or_null(Symbol*, Handle, Handle, Thread*)+0x26d
>> V  [libjvm.so+0xcde435]  SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*)+0x39
>> V  [libjvm.so+0x98c89e]  find_class_from_class_loader(JNIEnv_*, Symbol*, unsigned char, Handle, Handle, unsigned char, Thread*)+0x49
>> V  [libjvm.so+0x96f681]  JVM_FindClassFromCaller+0x39d
>> C  [libjava.so+0xdfd0]  Java_java_lang_Class_forName0+0x130
>> j  java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+0
>> j  java.lang.Class.forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;+49
>> j  ParallelTransformerLoaderAgent$TestTransformer.loadClasses(I)V+25
>> j  ParallelTransformerLoaderAgent$TestTransformer.transform(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[B)[B+81
>> j  sun.instrument.TransformerManager.transform(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[B)[B+50
>> j  sun.instrument.InstrumentationImpl.transform(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[BZ)[B+34
>> v  ~StubRoutines::call_stub
>> V  [libjvm.so+0x8c3060]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x6b2
>> V  [libjvm.so+0xba06bc]  os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x3a
>> V  [libjvm.so+0x8c29a7]  JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+0x7d
>> V  [libjvm.so+0x911bfb]  jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x3cd
>> V  [libjvm.so+0x916918]  jni_CallObjectMethod+0x388
>> C  [libinstrument.so+0x4eb5]  transformClassFile+0x1e5
>> C  [libinstrument.so+0x1e06]  eventHandlerClassFileLoadHook+0x96
>> V  [libjvm.so+0xa04afa]  JvmtiClassFileLoadHookPoster::post_to_env(JvmtiEnv*, bool)+0x1a8
>> V  [libjvm.so+0xa0485e]  JvmtiClassFileLoadHookPoster::post_all_envs()+0x8a
>> V  [libjvm.so+0xa047c6]  JvmtiClassFileLoadHookPoster::post()+0x18
>> V  [libjvm.so+0x9fb6e1]  JvmtiExport::post_class_file_load_hook(Symbol*, Handle, Handle, unsigned char**, unsigned char**, JvmtiCachedClassFileData**)+0x85
>> V  [libjvm.so+0x5cd17d]  ClassFileParser::parseClassFile(Symbol*, ClassLoaderData*, Handle, KlassHandle, GrowableArray<Handle>*, TempNewSymbol&, bool, Thread*)+0x2af
>> V  [libjvm.so+0x5dd441]  ClassFileParser::parseClassFile(Symbol*, ClassLoaderData*, Handle, TempNewSymbol&, bool, Thread*)+0x95
>> V  [libjvm.so+0x5daf03]  ClassLoader::load_classfile(Symbol*, Thread*)+0x2ed
>> V  [libjvm.so+0xce1cc4]  SystemDictionary::load_instance_class(Symbol*, Handle, Thread*)+0x118
>> V  [libjvm.so+0xce00a8]  SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*)+0x824
>> V  [libjvm.so+0xcde9e5]  SystemDictionary::resolve_or_null(Symbol*, Handle, Handle, Thread*)+0x26d
>> V  [libjvm.so+0xcde435]  SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*)+0x39
>> V  [libjvm.so+0x690fbc]  ConstantPool::klass_at_impl(constantPoolHandle, int, Thread*)+0x3cc
>> V  [libjvm.so+0x5398cb]  ConstantPool::klass_at(int, Thread*)+0x55
>> V  [libjvm.so+0x8b1f3c]  InterpreterRuntime::_new(JavaThread*, ConstantPool*, int)+0x14a
>> j  sun.misc.URLClassPath$JarLoader.checkResource(Ljava/lang/String;ZLjava/util/jar/JarEntry;)Lsun/misc/Resource;+42
>> j  sun.misc.URLClassPath$JarLoader.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+54
>> j  sun.misc.URLClassPath.getResource(Ljava/lang/String;Z)Lsun/misc/Resource;+53
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Class;+26
>> j  java.net.URLClassLoader$1.run()Ljava/lang/Object;+1
>> v  ~StubRoutines::call_stub
>> V  [libjvm.so+0x8c3060]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x6b2
>> V  [libjvm.so+0xba06bc]  os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x3a
>> V  [libjvm.so+0x8c29a7]  JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+0x7d
>> V  [libjvm.so+0x972a80]  JVM_DoPrivileged+0x63d
>> j  java.security.AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;+0
>> j  java.net.URLClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class;+13
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class;+70
>> j  java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class;
>> v  ~StubRoutines::call_stub
>> V  [libjvm.so+0x8c3060]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x6b2
>> V  [libjvm.so+0xba06bc]  os::os_exception_wrapper(void (*)(JavaValue*, methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x3a
>> V  [libjvm.so+0x8c29a7]  JavaCalls::call(JavaValue*, methodHandle, JavaCallArguments*, Thread*)+0x7d
>> V  [libjvm.so+0x8c1ec7]  JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x1cb
>> V  [libjvm.so+0x8c2086]  JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Handle, Thread*)+0xb0
>> V  [libjvm.so+0xce2096]  SystemDictionary::load_instance_class(Symbol*, Handle, Thread*)+0x4ea
>> V  [libjvm.so+0xce00a8]  SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*)+0x824
>> V  [libjvm.so+0xcde9e5]  SystemDictionary::resolve_or_null(Symbol*, Handle, Handle, Thread*)+0x26d
>> V  [libjvm.so+0xcde435]  SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*)+0x39
>> V  [libjvm.so+0x98c89e]  find_class_from_class_loader(JNIEnv_*, Symbol*, unsigned char, Handle, Handle, unsigned char, Thread*)+0x49
>> V  [libjvm.so+0x96f681]  JVM_FindClassFromCaller+0x39d
>> C  [libjava.so+0xdfd0]  Java_java_lang_Class_forName0+0x130
>> j  java.lang.Class.forName0(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+0
>> j  java.lang.Class.forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;+49
>> j  ParallelTransformerLoaderApp.loadClasses(I)V+25
>> ...<more frames>...



More information about the jdk9-dev mailing list