oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.09k stars 1.6k forks source link

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

Open roberttoyonaga opened 3 months ago

roberttoyonaga commented 3 months ago

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

fernando-valdez commented 3 months ago

Thanks for reporting this. I will take a look at this issue.

roberttoyonaga commented 3 months ago

@fernando-valdez another manifestation of the issue was reported back in 2020: https://github.com/oracle/graal/issues/2989

Do you know why the substitution Target_jdk_internal_loader_BootLoader#getDefinedPackage(String) is necessary? It seems to be the source of this problem.