【问题标题】:No instances of ... are allowed in the image heap as this class should be initialized at image runtime图像堆中不允许有 ... 的实例,因为此类应在图像运行时初始化
【发布时间】:2019-11-23 19:47:13
【问题描述】:

我正在使用以下堆栈运行一个简单的 Java 应用程序(只是一个 REST 端点,一个“Hello”响应 - 正是由 Quarkus maven 原型生成的示例,无需修改):

  • Quarkus(微配置文件)
  • JDK 1.8 热点 1.8.0_231-b11
  • GraalVM 19.3.0(本机映像)
  • MacOS Catalina

这是第一个错误(虽然它似乎不是主要问题):

[code-with-quarkus-1.0.0-SNAPSHOT-runner:1868]        setup:   8,524.65 ms
java.lang.NoSuchMethodException: com.oracle.svm.core.jdk.LocalizationSupport.addBundleToCache(java.lang.String)
    at java.lang.Class.getDeclaredMethod(Class.java:2130)
    at io.quarkus.runner.AutoFeature.beforeAnalysis(AutoFeature.zig:744)
    at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$7(NativeImageGenerator.java:669)
    at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:63)
    at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:669)
    at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:530)
    at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:445)
    at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
    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)
20:17:42,508 INFO  [org.jbo.threads] JBoss Threads version 3.0.0.Final
[code-with-quarkus-1.0.0-SNAPSHOT-runner:1868]   (typeflow):  34,257.18 ms
[code-with-quarkus-1.0.0-SNAPSHOT-runner:1868]    (objects):  19,361.86 ms
[code-with-quarkus-1.0.0-SNAPSHOT-runner:1868]   (features):     866.06 ms
[code-with-quarkus-1.0.0-SNAPSHOT-runner:1868]     analysis:  56,364.44 ms

真正的问题(我认为)在这里:

Error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of java.net.Inet4Address are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use -H:+TraceClassInitialization.
Detailed message:
Trace:
    at parsing org.wildfly.common.net.CidrAddress.<clinit>(CidrAddress.java:46)
Call path from entry point to org.wildfly.common.net.CidrAddress.<clinit>():
    no path found from entry point to target method

所以,我尝试的第一件事是指示类 org.wildfly.common.net.CidrAddress 不要在 Image BuildTime 初始化,而是在 Image RunTime 初始化,配置如下:

quarkus.native.additional-build-args=--initialize-at-run-time=org.wildfly.common.net.CidrAddress
quarkus.native.enable-jni=true 

但是,没有任何改变。我还尝试激活(按照指示)参数 -H:+TraceClassInitialization,以找出可能导致问题的正在初始化的类。没有效果!这个参数没有任何区别(没有额外的信息)。

是否有其他人经历过这种情况?任何提示,想法?

谢谢!

【问题讨论】:

    标签: quarkus graalvm-native-image


    【解决方案1】:

    Quarkus 尚不支持 GraalVM 19.3.0,它刚刚发布,需要进行一些更改。

    特别是您遇到了这个问题: - https://github.com/quarkusio/quarkus/pull/5353

    我希望 Quarkus 1.1 支持 GraalVM 19.3,但我不确定。

    【讨论】:

    • 谢谢@Sanne,问题出在不兼容的版本上(Quarkus 1.0 与 GraalVM 19.3.0),将 GraalVM 更改为 19.2.1 版本,它工作得非常完美!
    【解决方案2】:

    我的多阶段构建遇到了同样的问题:

    首先我修改了我的 pom.xml:

              <build>
                <plugins>
                    <plugin>
                        <groupId>io.quarkus</groupId>
                        <artifactId>quarkus-maven-plugin</artifactId>
                        <version>${quarkus.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>native-image</goal>
                                </goals>
                                <configuration>
                                    <enableHttpUrlHandler>true</enableHttpUrlHandler>
                                    <enableHttpsUrlHandler>true</enableHttpsUrlHandler>
                                    <enableJni>true</enableJni>
                                    <additionalBuildArgs>--initialize-at-run-time=java.net.Inet6Address -H:+TraceClassInitialization</additionalBuildArgs>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
    

    还是一样的错误...

    然后我将 Dockerfile 的基本映像从 FROM quay.io/quarkus/centos-quarkus-maven:19.3.0-java8 AS build 更改为 FROM quay.io/quarkus /centos-quarkus-maven:19.2.1 AS build 这是我完整的 Dockerfile.multistage:

    FROM quay.io/quarkus/centos-quarkus-maven:19.2.1 AS build
    COPY src /usr/src/app/src
    COPY pom.xml /usr/src/app/pom.xml
    USER root
    RUN chown -R quarkus /usr/src/app
    USER quarkus
    RUN mvn -f /usr/src/app/pom.xml -Pnative clean package
    
    ## Stage 2 : create the docker final image
    FROM registry.access.redhat.com/ubi8/ubi-minimal
    WORKDIR /work/
    COPY --from=build /usr/src/app/target/*-runner /work/application
    RUN chmod 775 /work
    EXPOSE 8080
    CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
    

    【讨论】:

    • 谢谢您的回答,但实际上我不是(仍然)生成Docker Image,我还是前一步,我只想要本地生成的Native(可执行文件),而不是Docker Image,所以我认为 Dockerfile 在这个问题上没有任何作用(至少是我的),命令是:mvn package -Pnative(与 Dockerfile 无关)。无论如何,谢谢!
    • 使用 $GRAALVM_HOME/bin/lli --version 检查您的 GRAALVM 版本,如果是 19.3.0,切换到 19.2.1 可能会有所帮助。如果您使用的是 https、ssl,您可能也想看看这个:github.com/quarkusio/quarkus/issues/2125我在那里失去了一个小时......
    • 谢谢,@NikolayKostadinov,正如 Sanne 所解释的,问题出在版本上,Quarkus 1.0 还没有为 GraalVM 19.3.0 做好准备,将 GraalVM 更改为 19.2.1 版本,它工作得非常完美!干杯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多