RFR(M): 8199852: Print more information about class loaders in LinkageErrors.

David Holmes david.holmes at oracle.com
Thu Mar 29 01:54:47 UTC 2018


Hi Mandy

On 29/03/2018 11:33 AM, mandy chung wrote:
> 
> 
> On 3/27/18 9:22 AM, David Holmes wrote:
>> Hi Lois,
>>
>> <trimming>
>>
>> On 27/03/2018 5:58 AM, Lois Foltan wrote:
>>> On 3/25/2018 5:48 PM, David Holmes wrote:
>>>> Maybe it makes sense to have a set pattern for this descriptive 
>>>> text, and use "unnamed" if the loader has no name:
>>>>
>>>> loader <name>, instanceof <class>, child of loader <name> ...
>>>>
>>>> not sure how much detail about the parent is needed.
>>>
>>> I do not support the above pattern for the descriptive text. The 
>>> supported pattern has already been documented within the API Note of 
>>> StackTraceElement.toString(), 
>>> https://docs.oracle.com/javase/9/docs/api/java/lang/StackTraceElement.html. 
>>
>>
>> Sorry Lois but I don't see that the toString() method of 
>> StackTraceElement is an authoritive definition of how loaders should 
>> be described in other contexts. 
> 
> I think Lois suggests to consider the well-defined pattern used in 
> printing stack trace when appropriate.  It's designed to be compact and 
> provide the adequate information for troubleshooting.
> 
> Reading JDK-8199940 and JDK-8199852, a relevant format is the exception 
> message in IllegalAccessError (and IllegalAccessException thrown by core 
> reflection) that I have added a comment in
> 
> class $FROM_CLASS (in $FROM_MODULE) cannot access class $TO_CLASS (in 
> $TO_MODULE) because $TO_MODULE does not export $PACKAGE_OF_TO_CLASS to 
> $FROM_MODULE
> 
> The format of the module is:
>     if it's a named module, it will print as "module $MODULE"
>     if it's an unnamed module, it will print as "unnamed module 
> @0xnnnnnnnn" where 0xnnnnnnnn is the identity hash code of the module.
> 
> A module is defined to one class loader.

That is not relevant here as we are dealing with classloader names, not 
modules.

>> That toString definition has to combine module, loader, class and 
>> method, information in a compact form. But that is not what we are 
>> dealing with here. Had I been involved in that work I would have also 
>> argued against completely omitting loader information in the un-named 
>> case.
> 
> Omitting the builtin class loader has no loss of information for 
> troubleshooting. The boot loader, platform loader  and app loader each 
> has one unnamed module.   The packages defined to a named module are 
> fixed.   It may not look obviously to which class loader/unnamed module 
> the class of the stack frame is defined.

We're talking about unnamed classloaders not the unnamed modules.

>>
>>> For example, the preference as stated for "unnamed" loaders is:
>>>
>>> If the class loader is abuilt-in class loader 
>>> <https://docs.oracle.com/javase/9/docs/api/java/lang/ClassLoader.html#builtinLoaders>or 
>>> is not named then the first element and its following|"/"|are omitted 
>>> as shown in "|acme at 2.1/org.acme.Lib.test(Lib.java:80)|"
>>>
>>> Again, Klass::class_loader_module_name() already implement and adhere 
>>> to this pattern.
>>
>> Yes but we are not dealing with module names here. And the fact it 
>> completely ignores un-named loaders makes it inherently unsuitable for 
>> the current context.
>>
>> The issue of whether information about the parent loader is suitable 
>> for the error message or should be left for logging, depends on how 
>> you expect these messages to help. If the idea is for the exception 
>> message to provide enough information for a support engineer to be 
>> able to diagnose a problem without asking the submitter to re-run with 
>> logging enabled, then you want to gather as much relevant information 
>> as possible. But a line has to be drawn somewhere. I don't think 
>> listing the loader's parent is excessive in this case, but nor do I 
>> see it as essential.
>>
> 
> I share Lois's concern in including the parent loader in the error message.
> 
> The parent loader does not cover all cases.   A well-defined class 

The intent is not to imply that you can tell how/if a loader delegates 
simply by listing its parent. The listing of the parent simply serves to 
tell you what the parent is - no more, no less.

Cheers,
David
-----

> loader follows the parent class loader delegation model.  But there are  
> custom class loaders that can delegate to more than one class loaders.  
> ClassLoader::getParent does not show the class loader delegation it 
> uses.  The class loader defining a named module may delegate to one or 
> more class loaders, each is the class loader defining one module 
> dependence.  If M requires M1 and M2, M1 and M2 may be defined to 
> different class loaders while M's loader::getParent may return a class 
> loader that is not M1's and M2's loader.
> 
> In any case, improving the error message for LinkageError is good but it 
> probably worths taking the time to agree on the format for a named and 
> unnamed class loader and its type.  I will give some thought and add the 
> JBS issue of any suggestion.
> 
> Mandy


More information about the hotspot-runtime-dev mailing list