Skip to content

[GR-53706] Behaviour of Class#getPackage() in Native Image is different than Java for Proxy classes  #8796

@roberttoyonaga

Description

@roberttoyonaga

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. The JfrSymbolRepository 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.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions