RFR(M): 8199852: Print more information about class loaders in LinkageErrors.
mandy chung
mandy.chung at oracle.com
Thu Mar 29 01:33:20 UTC 2018
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 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.
>
>> 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
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