RFR: 8038468: java/lang/instrument/ParallelTransformerLoader.sh fails with ClassCircularityError
Yumin Qi
yumin.qi at oracle.com
Tue Oct 14 18:40:24 UTC 2014
David, Thanks for the comment. See embedded.
On 10/13/2014 7:30 PM, David Holmes wrote:
> Hi Yumin,
>
> jdk9-dev is not the best place for code review requests.
> serviceability-dev would be better for this test.
>
> On 14/10/2014 8:58 AM, Yumin Qi wrote:
>> bug: https://bugs.openjdk.java.net/browse/JDK-8038468
>> webrev:*http://cr.openjdk.java.net/~minqi/8038468/webrev00/
>>
>> the bug marked as confidential so post the webrev internally.
>
> Not any more :)
>
Thanks. I changed to non security related bug. Usually when test failed,
a confidential bug is filed. I would like to create bug open if the test
is in open part.
>> Problem: The test case tries to load a class from the same jar via agent
>> in the middle of loading another class from the jar via same class
>> loader in same thread. The call happens in transform which is a rare
>> case --- in middle of loading class, loading another class. The result
>> is a CircularityError. When first class is in loading, in vm we put
>> JarLoader$2 on place holder table, then we start the defineClass, which
>> calls transform, begins loading the second class so go along the same
>> routine for loading JarLoader$2 first, found it already in placeholder
>> table. A CircularityError is thrown.
>> Fix: The test case should not call loading class with same class loader
>> in same thread from same jar in 'transform' method. I modify it loading
>> with system class loader and we expect see ClassNotFoundException.
>> Detail see bug comments.
>
> It is not clear to me that the test is incorrect. It is also unclear
> why such an old test is now failing - we must have changed something.
> And it's unclear whether what the test does with your change is
> actually testing what the test wanted to test.
>
> It seems to me that the actual problem in the test is the reference to
> the "main" thread ie:
>
> if (!tName.equals("main"))
>
> The test knows not to do the loading in the main thread, but has
> overlooked the fact that the main thread, upon the end of main()
> becomes the DestroyJavaVM thread - and it is that thread which
> encounters the ClassCircularityError:
>
> Starting test with 1000 iterations
> Thread 'DestroyJavaVM' has called transform()
>
> So perhaps the right fix is to expand the above to:
>
> if (!tName.equals("main") && !tName.equals("DestroyJavaVM"))
>
> ? I admit I'm having trouble seeing the full picture in this test.
>
It is not DestroyJavaVM thread cause CircularityError. It is TestThread
cause CircularityError.
In TestThread (DestroyJavaVM may cause same I think, but not seen in debug):
forName("TestClass2", true, classLoader); <---- the loader is
customer loader which is obtained from agent code.
-->...... transform(...)
-->defineClass(...)
-->...... call into vm, we need to load JarLoader$2
since JarLoader$1 used
->resolve_instance_class_or_null
// here we create PlaceTableEntry for
JarLoader$2, put into place holder table
-->......
--->forName("TestClass3", true,
classLoader);
-->... transform(...)
-->defineClass(...)
-->...... call into vm
again. Now JarLoader$2 is not loaded, but it is in placeholder table, so
throw_circularity_error set and throw.
.......
With custom loader, agent's transform will be called, then it
loads TestClass3, repeat the same steps as loading TestClass2. The
problem is JarLoader$2 has not been loaded yet but in place holder table
(this is for checking CircularityError), then begins loading TestClass3,
this is a recursive and embedded case. The non-failed case also saw
CircularityError thrown, but somehow the test case did not fail. Design
like this will cause call transform in transform which is the reason
CircularityError thrown.
I have no idea about the original desin of the test case, but think
it should do this.
>
> Looking at your change, don't leave commented out lines in the code:
> 115 // ClassLoader loader =
> ParallelTransformerLoaderAgent.getClassLoader();
> 118 //Class.forName("TestClass" +
> index, true, loader);
>
Will remove
Thanks
Yumin
> Thanks,
> David
>
>> Thanks
>> Yumin *
More information about the serviceability-dev
mailing list