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.21k stars 1.62k forks source link

[GR-57707] native-image-agent omits String[] from "serialization" when using newConstructorForSerialization #9581

Open Karm opened 2 weeks ago

Karm commented 2 weeks ago

As I was looking at https://github.com/oracle/graal/issues/8509#issue-2166454310 using native-agent to generate serialization config, it occurred to me that while e.g. both java.lang.Short[] and java.lang.String[][] get generated in the reachability-metadata.json, the java.lang.String[] is not added and has to be added manually. It's not a new thing though, I can see it both with older graalvm-community-jdk21u and with the very latest graalvm-community-java24.

How to reproduce

Using this source Main.java.zip TL;DR:

        Class[] arrayTypes = new Class[] {
...
                Short[][].class,
                String[].class,
                String[][].class,
...
        };
        for (int i = 0; i < arrayTypes.length; i++) {
            Constructor<?> cons = java.lang.Object.class.getDeclaredConstructor((Class[]) null);
            cons = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(arrayTypes[i], cons);
            System.out.println(cons.getParameterCount());
            Object o = Array.newInstance(arrayTypes[i].getComponentType(), 0);
            System.out.println(o.getClass().descriptorString());
        }
$ native-image --version
native-image 24 2025-03-18
GraalVM Runtime Environment GraalVM CE 24-dev+12.1 (build 24+12-jvmci-b01)
Substrate VM GraalVM CE 24-dev+12.1 (build 24+12, serial gc)

$ java --version
openjdk 24 2025-03-18
OpenJDK Runtime Environment GraalVM CE 24-dev+12.1 (build 24+12-jvmci-b01)
OpenJDK 64-Bit Server VM GraalVM CE 24-dev+12.1 (build 24+12-jvmci-b01, mixed mode, sharing)

$ unzip Main.java.zip

$ javac Main.java

$ java -agentlib:native-image-agent=config-output-dir=AGENT Main

$ native-image -ea --no-fallback --link-at-build-time -H:ConfigurationFileDirectories=./AGENT Main

$ ./main
...
Exception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: SerializationConstructorAccessor class not found for declaringClass: [Ljava.lang.String; (targetConstructorClass: java.lang.Object). Usually adding [Ljava.lang.String; to serialization-config.json fixes the problem.
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:121)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.serialize.SerializationSupport.getSerializationConstructorAccessor(SerializationSupport.java:205)
    at java.base@24/jdk.internal.reflect.SerializationConstructorAccessorGenerator.generateSerializationConstructor(SerializationConstructorAccessorGenerator.java:53)
    at java.base@24/jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:340)
    at java.base@24/jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:253)
    at jdk.unsupported@24/sun.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:100)
    at Main.main(Main.java:83)
    at java.base@24/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

When I edit the AGENT/reachability-metadata.json file as suggested by the helpful message:

  {
    "type": "java.lang.Short[][]",
    "customTargetConstructorClass": "java.lang.Object"
  },
+ {
+   "type": "java.lang.String[]",
+   "customTargetConstructorClass": "java.lang.Object"
+ },
  {
    "type": "java.lang.String[][]",
    "customTargetConstructorClass": "java.lang.Object"
  },

and run the build again, it works.

Is this expected of the native agent?

(@zakkak FYI)

fernando-valdez commented 2 weeks ago

Thanks for reporting this issue. Created GR-57707 for internal tracking

zakkak commented 2 weeks ago

cc @vjovanov

vjovanov commented 2 weeks ago

Not expected behavior, I will look into this early next week.