-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Describe the issue
If Class#getPackage()
is called when a proxy class's classloader is null, Native Image creates and returns a new Package
.
Class#getPackage()
-->
BootLoader#definePackage(Class<?> )
-->
Target_jdk_internal_loader_BootLoader#getDefinedPackage(String)
-->
Target_java_lang_Package(name, null, null, null,null, null, null, null, null);
However, in regular Java mode, if Class#getPackage()
is called and the class's classloader isn't set, a package isn't necessarily returned.
bash-4.4$ ./proxyreproducer
is proxy: true
clazz.getName(): jdk.proxy1.$Proxy65
clazz.getPackageName(): jdk.proxy1
clazz.getPackage(): package jdk.proxy1
clazz.getModule(): module jdk.proxy1
clazz.getClassLoader(): null
bash-4.4$ $JAVA_HOME/bin/java ProxyReproducer
is proxy: true
clazz.getName(): jdk.proxy1.$Proxy1
clazz.getPackageName(): jdk.proxy1
clazz.getPackage(): null
clazz.getModule(): module jdk.proxy1
clazz.getClassLoader(): null
Steps to reproduce the issue
See here for a simple reproducer: https://github.com/roberttoyonaga/ProxyReproducer/tree/main
Describe GraalVM and your environment:
GraalVM for JDK 22 CE linux amd x64
More info
-
When
Class#getPackage()
is called on proxy classes in Java mode, a package is sometimes returned if the class's classloader has been set. -
This difference in behaviour is a problem for JFR because if
Class#getPackage()
returns null in hosted mode, that package will not be registered and will be excluded from the image heap. TheJfrSymbolRepository
relies on symbol strings residing in the image heap and having immovable addresses. At Native Image runtime, SubstrateVM may construct a package instance for a class that otherwise wouldn't have one in Java mode. JFR will then treat that package instance normally and assume it is in the image heap, when it may actually not be.