Graal: Native image compilation error

Created on 18 Nov 2017  路  13Comments  路  Source: oracle/graal

I'm trying to compile to native image a very simple Java application, but it fails.
It's main method that serializes some object using Jackson.
JAR link: https://drive.google.com/file/d/1pjo0StwvDV_e0x_-SjMVdHubQS4AHkNl/view?usp=sharing

Source:

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

    public static void main(String... args) throws Exception {
        System.out.println(new ObjectMapper().writeValueAsString(new Car("Ferrari")));
    }
}

Command:
./native-image -verbose -jar test-graal-1.0-SNAPSHOT-fat.jar

Log:

Executing [
/graalvm-0.29/jre/bin/java \
-server \
-XX:+UnlockExperimentalVMOptions \
-XX:+EnableJVMCI \
-XX:-UseJVMCIClassLoader \
-XX:-UseJVMCICompi`r \
-d64 \
-noverify \
-Xbootclasspath/a:/graalvm-0.29/jre/lib/boot/graaljs-scriptengine.jar:/graalvm-0.29/jre/lib/boot/graal-sdk.jar \
-cp \
/graalvm-0.29/jre/lib/svm/svm.jar:/graalvm-0.29/jre/lib/svm/objectfile.jar:/graalvm-0.29/jre/lib/svm/pointsto.jar:/graalvm-0.29/jre/lib/svm/svm-enterprise.jar:/graalvm-0.29/jre/lib/jvmci/graal.jar:/graalvm-0.29/jre/lib/jvmci/enterprise-graal.jar:/graalvm-0.29/jre/lib/jvmci/jvmci-api.jar:/graalvm-0.29/jre/lib/jvmci/jvmci-hotspot.jar \
-Duser.country=US \
-Duser.language=en \
-Dgraal.EagerSnippets=true \
-Dsubstratevm.version=1201e5c00c8dc7d0cdb2056c902ad20990c94669 \
-Dgraalvm.version=0.29 \
-Dorg.graalvm.version=0.29 \
-Xms1G \
-Xss10m \
-Dcom.oracle.graalvm.isaot=true \
com.oracle.svm.hosted.NativeImageGeneratorRunner \
-imagecp \
/graalvm-0.29/jre/lib/svm/svm.jar:/graalvm-0.29/jre/lib/svm/objectfile.jar:/graalvm-0.29/jre/lib/svm/pointsto.jar:/graalvm-0.29/jre/lib/svm/svm-enterprise.jar:/graalvm-0.29/jre/lib/jvmci/graal.jar:/graalvm-0.29/jre/lib/jvmci/enterprise-graal.jar:/graalvm-0.29/jre/lib/jvmci/jvmci-api.jar:/graalvm-0.29/jre/lib/jvmci/jvmci-hotspot.jar:/graalvm-0.29/jre/lib/svm/library-support.jar:/graalvm-0.29/bin/test-graal-1.0-SNAPSHOT-fat.jar:/graalvm-0.29/bin \
-H:Path=. \
-H:InspectServerContentPath=/graalvm-0.29/jre/lib/svm/inspect \
-H:CLibraryPath=/graalvm-0.29/jre/lib/svm/clibraries/darwin-amd64 \
-H:Class=panga.test.graal.Main \
-H:Name=test-graal-1.0-SNAPSHOT-fat
]
   classlist:   1,084.77 ms
       (cap):     729.15 ms
       setup:   1,411.76 ms
    analysis:   2,837.07 ms
error: Error encountered while parsing com.oracle.svm.reflect.proxies.Proxy_1_EnumMap_keyType.get(java.lang.Object) 
Parsing context:
    parsing java.lang.reflect.Field.get(Field.java:393)
    parsing com.fasterxml.jackson.databind.introspect.AnnotatedField.getValue(AnnotatedField.java:116)
    parsing com.fasterxml.jackson.databind.ser.std.JsonValueSerializer.serializeWithType(JsonValueSerializer.java:194)
    parsing com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer.serializeWithType(StdDelegatingSerializer.java:183)
    parsing com.fasterxml.jackson.databind.ser.impl.TypeWrappedSerializer.serialize(TypeWrappedSerializer.java:32)
    parsing com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    parsing com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
    parsing com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3893)
    parsing com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3207)
    parsing panga.test.graal.Main.main(Main.java:9)
    parsing com.oracle.svm.core.JavaMainWrapper.run(stripped:133)
    parsing Lcom/oracle/svm/core/code/b;.com_002eoracle_002esvm_002ecore_002eJavaMainWrapper_002erun_0028int_002corg_002egraalvm_002enativeimage_002ec_002etype_002eCCharPointerPointer_0029(generated:0)
Original error: org.graalvm.compiler.debug.GraalError: failed guarantee: Could not find class com.oracle.svm.E.a.createFailedCast (static)
    at org.graalvm.compiler.debug.GraalError.guarantee(GraalError.java:121)
    at org.graalvm.compiler.replacements.GraphKit.findMethod(GraphKit.java:209)
    at com.oracle.svm.reflect.hosted.i.a(stripped:151)
    at com.oracle.svm.reflect.hosted.i.a(stripped:175)
    at com.oracle.svm.reflect.hosted.i.b(stripped:51)
    at com.oracle.svm.reflect.hosted.i$f.buildGraph(stripped:336)
    at com.oracle.graal.pointsto.meta.AnalysisMethod.buildGraph(AnalysisMethod.java:270)
    at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:138)
    at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:288)
    at com.oracle.graal.pointsto.flow.MethodTypeFlow.doParse(MethodTypeFlow.java:318)
    at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureParsed(MethodTypeFlow.java:308)
    at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:88)
    at com.oracle.graal.pointsto.DefaultAnalysisPolicy$DefaultVirtualInvokeTypeFlow.update(DefaultAnalysisPolicy.java:220)
    at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:467)
    at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:154)
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Error: Image building with exit status 1

Most helpful comment

We now have support for synchronization on strings and arrays.

All 13 comments

Hi, thanks for reporting. This issue has been fixed. Still the code that you would like to build fails with the following two errors:

Error: Bytecode parsing error: Unsupported method java.lang.Class.getPackage() is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
To diagnose the issue, you can add the option -H:+ReportUnsupportedElementsAtRuntime. The unsupported element is then reported at run time when it is accessed the first time.
Trace: 
    at parsing com.fasterxml.jackson.databind.util.ClassUtil.getPackageName(ClassUtil.java:1040)
Call path from entry point to com.fasterxml.jackson.databind.util.ClassUtil.getPackageName(Class): 
    at com.fasterxml.jackson.databind.util.ClassUtil.getPackageName(ClassUtil.java:1040)
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector._isStdJDKCollection(BasicClassIntrospector.java:247)
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector._findStdJdkCollectionDesc(BasicClassIntrospector.java:265)
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:85)
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:16)
    at com.fasterxml.jackson.databind.SerializationConfig.introspect(SerializationConfig.java:778)
...

Error: Bytecode parsing error: Unsupported method java.lang.ClassLoader.checkClassLoaderPermission(ClassLoader, Class) is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
To diagnose the issue, you can add the option -H:+ReportUnsupportedElementsAtRuntime. The unsupported element is then reported at run time when it is accessed the first time.
Trace: 
    at parsing java.lang.Thread.getContextClassLoader(Thread.java:1443)
Call path from entry point to java.lang.Thread.getContextClassLoader(): 
    at java.lang.Thread.getContextClassLoader(Thread.java:1439)
    at com.fasterxml.jackson.databind.util.ClassUtil.getClassMethods(ClassUtil.java:1089)
    at com.fasterxml.jackson.databind.introspect.AnnotatedMethodCollector._addMemberMethods(AnnotatedMethodCollector.java:107)
    at com.fasterxml.jackson.databind.introspect.AnnotatedMethodCollector.collect(AnnotatedMethodCollector.java:42)
    at com.fasterxml.jackson.databind.introspect.AnnotatedMethodCollector.collectMethods(AnnotatedMethodCollector.java:32)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass._methods(AnnotatedClass.java:365)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass.memberMethods(AnnotatedClass.java:305)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addInjectables(POJOPropertiesCollector.java:660)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:315)
...

Both of these errors could be fixed. Would you like us to look into these issues?

These issues can be removed by adding -H:+ReportUnsupportedElementsAtRuntime, then we need to include all types that are reflectively accessed with -H:ReflectionConfigurationFiles=<path_to_json> with the following content:

    [
      {
        "name" : "package.Car",
        "allDeclaredMethods" : "true",
        "allPublicMethods" : "true"
      }
    ]

But then we hit the following limitation:

UNSUPPORTED FEATURE: wait/notify called on non-instance type: char[]

We are currently working on removing this limitation, but it might take some time. If you need this soon please let us know so we can raise the priority. Contributions are also very welcome.

In case your application does not need multi-threading, you can use -H:-MultiThreaded in the image build command. This will make the program work and print the following:

$ svmbuild/main 
{"name":"Ferrari"}

@vjovanov thank you ! I got it working with the code snippet, although multi-threading environment is required and I need it to be working.

It's not clear to me if it's a GraalVM or SVM limitation.
Do you have plans to work on a fix?

It is the limitation of SVM at the moment: it does not allow synchronization on arrays and strings in order to keep them fully immutable. When they are immutable, they can be saved in the read-only part of the image.

This will be fixed with relatively high priority as this case happens very often. It is not a trivial fix and will not be fixed in the next two weeks. If it is important for you and you intend to use it please let me know to increase the priority.

Can you continue experimenting without the support for multi-threading?

Yes, I'll continue my tests with Graal meanwhile, I have another code snippets to test.
SVM multi-threading support is required in a final release.

We will support the missing bits sooner rather than later.

We now have support for synchronization on strings and arrays.

@vjovanov awesome!! Do you have a version number / ETA for next release? :)

This is the PR that introduces it. It is still basic support as if you change the arrays you synchronize on, it will leak memory. We are working on a solution that does not leak memory.

The release should out be by the end of next week.

The new release is out.

Above, @vjovanov says:

with the following content:

[
     {
        "name" : "package.Car",
        "allDeclaredMethods" : "true",
        "allPublicMethods" : "true"
    }
]

But it should be:

[
     {
        "name" : "package.Car",
        "allDeclaredMethods" : true,
        "allPublicMethods" : true
    }
]

In two places true (boolean) should be used instead of "true" (string)

I found this same error in some documentation and submitted a PR:
https://github.com/oracle/graal/pull/369

Was this page helpful?
0 / 5 - 0 ratings