JDK-8203849 : DelegatingClassLoader name could be used to indicate reflected class
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 11
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • Submitted: 2018-05-27
  • Updated: 2019-03-20
  • Resolved: 2019-03-20
Related Reports
Relates :  
Relates :  
Description
Core reflection uses one DelegatingClassLoader instance per Generated{Method|Constructor}Impl class.

Since there are often many of them and a list of "DelegatingClassLoader" loaders is not very enlightening in tools like jcmd, it may be useful to set its name (currently unused) to something which indicates the reflection target class.

Orginal credits for this idea go to my SAP colleague Ralf Schmelter.
Comments
No urgent need to do this since we have a working solution with a number of tools like VM.metaspace and VM.classloaders. Also, to me shoehorning the reflected class name into the CL name feels hackish.
20-03-2019

Moved to 12. With JDK-8203343 solved there is currently no urgent need for this.
14-06-2018

Hi Mandy, I have two patches which both solve the analysis problem of generated core reflection classes, each in a different way. This is one approach - piggybacking the loader name of the DelegatingClassLoader. The other patch goes under https://bugs.openjdk.java.net/browse/JDK-8203343 (b). It extracts target class name, method name and signature from the constant pool of a Generated{Method|Constructor}AccessorImpl class and prints that as an additional information in places where class names are printed. For an example which combines both approaches, please see: http://cr.openjdk.java.net/~stuefe/other/output-vm-classloaders-with-reflection.txt (I also attached it to this RFE). This is the output of "jcmd <vmid> VM.classloaders show-classes", where the VM contains both patches. That command prints out a class loader tree, in this case with all loaded classes. The VM did run a little Spring MVC example. You can see the many DelegatingClassLoaders when you scroll down. (Side note, "VM.classloaders" is another addition by us, currently up for RFR on serviceability-dev (JDK-8203682). Feel free to review, we are really strapped for reviewers :) The linked file is the output - the VM was running a little Spring MVC example - and you can see the DelegatingClassLoaders when you scroll down. Here an excerpt: +-- "REFLECT-ONTO-com/sun/proxy/$Proxy38" (instance of jdk.internal.reflect.DelegatingClassLoader) | | Classes: jdk.internal.reflect.GeneratedConstructorAccessor29 (invokes: com/sun/proxy/$Proxy38::<init> (Ljava/lang/reflect/InvocationHandler;)V) | (1 class) | +-- "REFLECT-ONTO-com/sun/proxy/$Proxy53" (instance of jdk.internal.reflect.DelegatingClassLoader) | | Classes: jdk.internal.reflect.GeneratedConstructorAccessor30 (invokes: com/sun/proxy/$Proxy53::<init> (Ljava/lang/reflect/InvocationHandler;)V) | (1 class) | +-- "REFLECT-ONTO-org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$221b0ba$$FastClassBySpringCGLIB$$be491fa0" (instance of jdk.internal.reflect.DelegatingClassLoader) Classes: jdk.internal.reflect.GeneratedConstructorAccessor31 (invokes: org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$221b0ba$$FastClassBySpringCGLIB$$be491fa0::<init> (Ljava/lang/Class;)V) (1 class) The first line of each tree node contains loader name and class, in this case the piggybacked DelegatingClassLoader name. I prefixed it with "REFLECT-ONTO-". Had no better idea. Below the class loader name you see a list of loaded classes. In this case, there is of course only one. Here I print out the complete invocation target - this is JDK-8203343. Both approaches have pros and cons. - Piggybacking the loader name of the DelegatingClassLoader makes it work out of the box wherever we print out loader names. However the name can get longish, as you can see in the example output. Also note I only set the loader name to the target class name and left out target method name/signature. Reason: I believe that one could bundle multiple Generated..Accessor classes in one DelegatingClassLoader (see discussion with P.Levart at http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-May/053150.html) to save metaspace and such an improvement would remove the 1:1 relationship between Generated..Accessor and DelegatingClassLoader. However, the DelegatingClassLoader will probably always be associated with one target class, so it is safe to use that target class name as the loader name. - JDK-8203343 will only work wherever one cares to add it - in my patch I added it to VM.metaspace and VM.classloaders, we may add it of course also to GC.class_stats, GC.class_histogram and wherever else we stare confused at walls of "GeneratedXXXAccessorXXX" output. Since JDK-8203343 works on the generated class itself instead of the DelegatingClassLoader, we do not have the 1:1 problem. In my opinion both approaches complement each other. What do you think?
30-05-2018

It's a fine idea to use the class loader name to improve the diagnosability. Note that the class loader name is shown in the stack trace. The reflected target class name may be quite long. The resulting stack trace output should be considered. It'd be helpful to include some example of jcmd output to show the usefulness.
29-05-2018