JDK-8199852 : Print more information about class loaders in LinkageErrors.
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 11
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-03-20
  • Updated: 2019-02-12
  • Resolved: 2018-05-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11
11 b13Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Print more information about class loaders in LinkageErrors. 
Since Java 9, class loaders have a name field. Report this if set.
Also report the parent class loader.

Changed messages:
=================

systemDictionary.cpp, 
---------------------------

SystemDictionary::check_constraints()
message 1:

before: 
loader (instance of PreemptingClassLoader): attempted duplicate class definition for name: "test/Foo"
loader (instance of PreemptingClassLoader): attempted duplicate class definition for name: "test/J"

after:
loader "<unnamed>" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) attempted duplicate class definition for test.Foo.
loader "DuplicateLE_Test_Loader" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) attempted duplicate class definition for test.Foo.
loader "DuplicateLE_Test_Loader_IF" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) attempted duplicate interface definition for test.J.

Improvements:
 * external names ('.' instead of '/')
 * more detailed loader description (name, class, parent)
 * distinguish classes, interfaces and abstract classes.

message 2:

before:
loader constraint violation: loader (instance of PreemptingClassLoader) previously initiated loading for a different type with name "test/D_ambgs"

after:
loader constraint violation: loader "<unnamed>" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) wants to load class test.D_ambgs. A different class with the same name was previously loaded by "app" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader).

Improvements: 

 * external names ('.' instead of '/')
 * more detailed loader description (name, class, parent)
 * distinguish classes, interfaces and abstract classes.


klassVtable.cpp:
---------------------

message 3, klassVtable::update_inherited_vtable():

before:

loader constraint violation for class test/Task: when selecting overriding method "test.Task.m()Ltest/Foo;" the class loader (instance of PreemptingClassLoader) of the selected method's type test/Task, and the class loader (instance of jdk/internal/loader/ClassLoaders$AppClassLoader) for its super type test/J have different Class objects for the type test/Foo used in the signature

after:

loader constraint violation for class test.Task: when selecting overriding method test.Task.m()Ltest/Foo; the class loader "<unnamed>" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) of the selected method's type test.Task, and the class loader "app" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) for its super type test.J have different Class objects for the type test.Foo used in the signature

or

loader constraint violation for class test.Task: when selecting overriding method test.Task.m()Ltest/Foo; the class loader "VtableLdrCnstrnt_Test_Loader" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) of the selected method's type test.Task, and the class loader "app" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) for its super type test.J have different Class objects for the type test.Foo used in the signature

message 4, klassItable::initialize_itable_for_interface():

before:

loader constraint violation in interface itable initialization for class test/C: when selecting method "test.I.m()Ltest/Foo;" the class loader (instance of PreemptingClassLoader) for super interface test/I, and the class loader (instance of jdk/internal/loader/ClassLoaders$AppClassLoader) of the selected method's type, test/J have different Class objects for the type test/Foo used in the signature

after:

loader constraint violation in interface itable initialization for class test.C: when selecting method test.I.m()Ltest/Foo; the class loader "<unnamed>" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) for super interface test.I, and the class loader "app" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) of the selected method's type, test.J have different Class objects for the type test.Foo used in the signature"

or

loader constraint violation in interface itable initialization for class test.C: when selecting method test.I.m()Ltest/Foo; the class loader "ItableLdrCnstrnt_Test_Loader" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader) for super interface test.I, and the class loader "app" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) of the selected method's type, test.J have different Class objects for the type test.Foo used in the signature

Improvements: 

 * external names ('.' instead of '/')
 * more detailed loader description (name, class, parent)

 * Todo: external name in method signature?!

linkResolver.cpp:
---------------------

message 5  LinkResolver::check_method_loader_constraints():
message 6 LinkResolver::check_field_loader_constraints():

replaced parts mentioning the class loader:

before:

the class loader (instance of PreemptingClassLoader)

after:

the class loader "<unnamed>" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader)

or:

the class loader "My_Test_Loader" (instance of PreemptingClassLoader, child of "app" jdk.internal.loader.ClassLoaders$AppClassLoader)


Comments
Goetz - when you check the code in, could you possibly update the description to match what you actually did so we can use this as an easy reference? Thanks.
02-05-2018

@dholmes: Each class loader has an un-named module. Any class in an unnamed package belongs to the unnamed module for the given class loader.
02-05-2018

Does the un-named module have a dedicated un-named classloader? If so that might be useful to know. But more generally the loader constraint errors only require additional information about the loader not about the type. For access control it is a different matter.
30-03-2018

Each class loader has a parent loader but a custom class loader could delegate to more than one class loaders. It's unclear how the parent loader is involved in these errors. Can you explain? These error messages include a type name which can include the module name and/or the class loader name to help diagnosis.
29-03-2018

[~dholmes] a module is defined to a class loader. A class loader can define one or more modules. What are you looking for when an error includes a type? I think the case you might be interested in is a class in unnamed module defined by an unnamed class loader??
29-03-2018

We're trying to cram in too much information. A type is a (typename, classloader) pair - the module is not directly relevant.
29-03-2018