graal icon indicating copy to clipboard operation
graal copied to clipboard

native-image: fails to create image with --language:js, types reachable for JIT compilation must not have linkage errors

Open ahoora08 opened this issue 3 years ago • 2 comments

Describe GraalVM and your environment :

  • GraalVM version or commit id if built from source: [21.3.1]
  • CE or EE: [CE]
  • JDK version: [JDK8]
  • OS and OS Version: [Linux Ubunti 22.04]
  • Architecture: [amd64]
  • The output of java -Xinternalversion:
 **OpenJDK 64-Bit Server VM GraalVM CE 21.3.1 (25.302-b06-jvmci-21.3-b05) for linux-amd64 JRE (1.8.0), built on Oct 16 2021 10:47:15 by "buildslave" with gcc 7.3.0**

Describe the issue Hello, I'm using ScriptEngine API to call some JS scripts in my application.

ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine jsEngine = sem.getEngineByName("graal.js");
.....
jsEngine.eval(mathFunctionScript)

In normal execution it's fine. Trying to package it as a native-image app I got NullPointerException when trying to call the eval method on the ScriptEngine instance at the runtime. After investigating some related issues here, I added --language:js to the build properties and then I got the below exceptions:

[app:7434]    classlist:  16,051.19 ms,  1.79 GB
[app:7434]        (cap):   1,107.08 ms,  2.37 GB
[app:7434]        setup:   6,493.77 ms,  2.37 GB
[app:7434]     analysis: 204,468.56 ms,  5.49 GB
Fatal error:com.oracle.svm.core.util.VMError$HostedError: types reachable for JIT compilation must not have linkage errors
        at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:68)
        at com.oracle.svm.core.util.VMError.guarantee(VMError.java:89)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createType(GraalObjectReplacer.java:290)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createField(GraalObjectReplacer.java:248)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createAllInstanceFields(GraalObjectReplacer.java:325)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createType(GraalObjectReplacer.java:301)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createField(GraalObjectReplacer.java:248)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createAllInstanceFields(GraalObjectReplacer.java:325)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createType(GraalObjectReplacer.java:301)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.createMethod(GraalObjectReplacer.java:214)
        at com.oracle.svm.graal.hosted.GraalObjectReplacer.updateDataDuringAnalysis(GraalObjectReplacer.java:369)
        at com.oracle.svm.graal.hosted.GraalFeature.duringAnalysis(GraalFeature.java:508)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$12(NativeImageGenerator.java:727)
        at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:73)
        at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:727)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:529)
        at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:488)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:569)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:122)
[app:7434]      [total]: 229,493.38 ms,  5.49 GB

Here is the list of the flags I'm using for building the image:

--verbose \
--no-fallback \
--enable-http \
--enable-https \
--allow-incomplete-classpath \
--enable-all-security-services \
--report-unsupported-elements-at-runtime \
--language:js \
-H:EnableURLProtocols=http,https \
-H:ReflectionConfigurationResources=${.}/reflect-config.json \
-H:ResourceConfigurationResources=${.}/resource-config.json \
-H:+ReportExceptionStackTraces \
--allow-incomplete-classpath \
--report-unsupported-elements-at-runtime \
--initialize-at-build-time=\
org.slf4j.LoggerFactory,\
org.slf4j.simple.SimpleLogger,\
org.slf4j.impl.StaticLoggerBinder,\
org.slf4j.MDC,\
ch.qos.logback,\
javax.xml.parsers.FactoryFinder,\
com.sun.org.apache.xerces.internal,\
javax.xml.datatype.DatatypeFactory,\
jdk.xml.internal.JdkXmlUtils \
--initialize-at-run-time=\
io.netty.util.internal.logging.Log4JLogger,\
io.netty.util.AbstractReferenceCounted,\
io.netty.channel.epoll,\
io.netty.handler.ssl,\
io.netty.channel.unix,\
io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod,\
io.netty.internal.tcnative.CertificateCompressionAlgo,\
io.netty.internal.tcnative.CertificateVerifier,\
io.netty.internal.tcnative.SSL,\
io.netty.internal.tcnative.SSLPrivateKeyMethod,\
io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod,\
io.netty.internal.tcnative.CertificateCompressionAlgo,\
io.netty.internal.tcnative.CertificateVerifier

Finally the version of the related dependencies:

<!-- GraalVM runtime -->
       <dependency>
            <groupId>org.graalvm.js</groupId>
            <artifactId>js-scriptengine</artifactId>
            <version>22.0.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.graalvm.truffle</groupId>
            <artifactId>truffle-api</artifactId>
            <version>22.0.0.2</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.graalvm.js</groupId>
            <artifactId>js</artifactId>
            <version>22.0.0.2</version>
            <scope>runtime</scope>
        </dependency>

The prerequisite packages are installed sudo apt-get install build-essential libz-dev zlib1g-dev

Update1 Exact same exception with GraalVM version CE 22.1.0 JDK 11:

[1/7] Initializing...                                                                                   (16.0s @ 0.36GB)
 Version info: 'GraalVM 22.1.0 Java 11 CE'
 C compiler: gcc (linux, x86_64, 11.2.0)
 Garbage collector: Serial GC
 1 user-provided feature(s)
  - com.oracle.svm.thirdparty.gson.GsonFeature

Update2 I found out that having below dependency is causing the exception. Removing it I get no exception at the build time and both building and execution are fine with --language:js flag.

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-micrometer-metrics</artifactId>
    <version>4.2.3</version>
</dependency>

Update3 By investigating the transitive dependencies I found out the conflict is exactly with this one

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
</dependency>

Here is a repos to reproduce the exception: https://github.com/ahoora08/graalvm-js

ahoora08 avatar Jun 19 '22 15:06 ahoora08

Hi Thank you for reporting this, we will take a look into it and get back to you

oubidar-Abderrahim avatar Jun 24 '22 08:06 oubidar-Abderrahim

Hello, Is there any update on this topic?

ahoora08 avatar Jul 15 '22 12:07 ahoora08

@ahoora08 how did you figure out which dependency was causing the break? I ran into the same error.

BaljeetSandhu avatar May 02 '23 21:05 BaljeetSandhu

I was able to get the native image to build successfully by adding the following dependencies to your pom.xml:

        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-influx</artifactId>
            <version>${micrometer.version}</version>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-jmx</artifactId>
            <version>${micrometer.version}</version>
        </dependency>

So this appears to simply be a consequence of missing dependencies, causing certain classes required by vertx-micrometer-metrics to not be found (the "linkage error" here is a NoClassDefFoundError).

Unfortunately, the error message here is not very helpful. We will try to improve it in newer versions.

woess avatar May 24 '23 18:05 woess

@woess is there any way to include problematic class in error message right now? I ran into a similiar error, but adding micrometer-registry-influx/micrometer-registry-jmx/both doesn't help (and I also already have micrometer-registry-prometheus). It's quite a stopper for a half of a year now (https://github.com/Tinkoff/mockingbird/pull/23) 😔

danslapman avatar May 27 '23 11:05 danslapman

@woess ? @ahoora08 ? how can you surface the failing class? how can you attach the debugger to find the missing dependency?

sgammon avatar Jul 26 '23 21:07 sgammon

Sorry for the late reply. I'm afraid there's isn't an easy way to surface the failing class.

The good news though is that this should be improved now by https://github.com/oracle/graal/commit/c6bf8cc1c5b4ccf0b1617847086ea692c3ee0f6f which will be included in the upcoming 24.0 and 23.1.2 releases. Until then, you could try out one of our dev builds.

woess avatar Dec 19 '23 17:12 woess

Sorry for the late reply. I'm afraid there's isn't an easy way to surface the failing class.

The good news though is that this should be improved now by https://github.com/oracle/graal/commit/c6bf8cc1c5b4ccf0b1617847086ea692c3ee0f6f which will be included in the upcoming 24.0 and 23.1.2 releases. Until then, you could try out one of our dev builds.

@woess The same issue occurs with the following dependencies, and is it now fixed in the next release

openjdk version "21.0.1" 2023-10-17
OpenJDK Runtime Environment GraalVM CE 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19, mixed mode, sharing)
<dependency>
        <groupId>org.graalvm.polyglot</groupId>
        <artifactId>polyglot</artifactId>
        <version>23.1.1</version>
</dependency>
<dependency>
        <groupId>org.graalvm.polyglot</groupId>
        <artifactId>js-community</artifactId>
        <version>23.1.1</version>
        <type>pom</type>
</dependency>

qa137 avatar Jan 17 '24 04:01 qa137