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.38k stars 1.63k forks source link

[GR-27596] ClassLoader class getPackage equal in Java but not equal in Native Image #2989

Open jiekang opened 3 years ago

jiekang commented 3 years ago

Describe the issue

The default ClassLoader class getPackage is equal in Java but not equal in Native Image. Is this an expected result?

Steps to reproduce the issue

public class PackageTest {
    public static void main(String[] args) {
        ClassLoader cl = PackageTest.class.getClassLoader();
        assert (cl != null);
        Class<?> c = cl.getClass();
        Package p1 = c.getPackage();
        Package p2 = c.getPackage();
        assert (p1 != null && p2 != null);
        System.err.println(p1.equals(p2));
    }
}
javac PackageTest.java
java PackageTest // prints true

mx native-image PackageTest
./packagetest //prints false

Describe GraalVM and your environment:

munishchouhan commented 3 years ago

@jiekang thanks for reporting the bug We will look into it

jiekang commented 3 years ago

Thanks. To be clear, I'm curious if this is intentional or not, but I'd also prefer that behavior was the same between Java and native image.

munishchouhan commented 3 years ago

@jiekang We have added this in our feature list and will be fixed in future releases, please do check out https://www.graalvm.org/ to get update on future releases.

jiekang commented 3 years ago

@mcraj017 Okay sounds good; I appreciate the communication!

roberttoyonaga commented 6 months ago

The reason there is a difference between native and Java mode is that this Native Image substitution causes classes loaded by the bootstrap class loader to construct new packages when Class#getPackage() is called. In regular Java, new package instances are not created.

So in @jiekang's example, 2 independent objects are created and compared. Thus not equal.

        Package p1 = c.getPackage();
        Package p2 = c.getPackage();

This is related to another open issue here: https://github.com/oracle/graal/issues/8796