【问题标题】:Quarkus Graalvm Native app ClassNotFoundException com.sun.xml.internal.ws.spi.ProviderImplQuarkus Graalvm 本机应用程序 ClassNotFoundException com.sun.xml.internal.ws.spi.ProviderImpl
【发布时间】:2020-03-25 22:07:10
【问题描述】:

我正在将 Spring Boot 应用程序转换为 Quarkus,作为概念证明。当我构建 Quarkus 应用程序并使用 Java 运行它时,它运行良好,但是当我尝试将它作为本机应用程序运行时,我在内部 sun 类 (com.sun. xml.internal.ws.spi.ProviderImpl),因为它在 Java 中运行,我希望 Native App 也能正常工作。

我正在使用:

  • Quarkus 1.3.0.final
  • 使用 quay.io/quarkus/ubi-quarkus-native-image:19.3.1-java11
  • 其中有 openjdk version "11.0.6" 2020-01-14 OpenJDK Runtime Environment GraalVM CE 19.3.1 (build 11.0.6+9-jvmci-19.3-b07) OpenJDK 64-Bit Server VM GraalVM CE 19.3.1 (build 11.0.6+9-jvmci-19.3-b07, mixed mode, sharing)
  • 使用 gradle 构建
------------------------------------------------------------
Gradle 6.2
------------------------------------------------------------

Build time:   2020-02-17 08:32:01 UTC
Revision:     61d3320259a1a0d31519bf208eb13741679a742f

Kotlin:       1.3.61
Groovy:       2.5.8
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          13.0.2 (AdoptOpenJDK 13.0.2+8)
OS:           Mac OS X 10.14.6 x86_64
  • 此项目使用 WSDL(插件号.nils.wsdl2java 0.12)
  • 我在 build.gradle 中添加了以下内容
   // wsdl2java JDK9+
   implementation 'com.sun.xml.bind:jaxb-xjc:2.3.0.1'
   implementation 'javax.xml.bind:jaxb-api:2.3.1'
   implementation 'javax.xml.ws:jaxws-api:2.3.1'
   implementation 'org.apache.cxf:cxf-rt-wsdl:3.2.7'
   implementation 'javax.jws:javax.jws-api:1.1'
//    implementation 'com.sun.xml.ws:rt:2.3.2'

gradle build 命令是

./gradlew buildNative -i --stacktrace --docker-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-native-image:19.3.1-java11

原生应用输出

我从 ubi-quarkus-native-image 中运行应用程序

[quarkus@79a141991f90 build]$./my-service-1.0.0-SNAPSHOT-runner 
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-03-25 21:44:21,365 INFO  [com.che.es.eng.HealthAggregator] (main) Initializing health checks for 3 engines!
2020-03-25 21:44:21,370 ERROR [com.che.es.eng.ExEngine] (taskScheduler-0) Error from Ex web services!: javax.xml.ws.WebServiceException: Provider com.sun.xml.internal.ws.spi.ProviderImpl not found
    at javax.xml.ws.spi.FactoryFinder$1.createException(FactoryFinder.java:61)
    at javax.xml.ws.spi.FactoryFinder$1.createException(FactoryFinder.java:58)
    at javax.xml.ws.spi.ServiceLoaderUtil.newInstance(ServiceLoaderUtil.java:103)
    at javax.xml.ws.spi.FactoryFinder.find(FactoryFinder.java:112)
    at javax.xml.ws.spi.Provider.provider(Provider.java:96)
    at javax.xml.ws.Service.<init>(Service.java:112)
    at com.che.es.engine.wsdl.AddressValidationService.<init>(AddressValidationService.java:39)
    at com.che.es.engine.FedExHealthIndicator$FedExHealthCheckerTask.run(FedExHealthIndicator.java:70)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.lang.Thread.run(Thread.java:834)
    at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:497)
    at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.ws.spi.ProviderImpl
    at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:60)
    at java.lang.ClassLoader.loadClass(Target_java_lang_ClassLoader.java:160)
    at javax.xml.ws.spi.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:90)
    at javax.xml.ws.spi.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:123)
    at javax.xml.ws.spi.ServiceLoaderUtil.newInstance(ServiceLoaderUtil.java:101)
    ... 16 more
2020-03-25 21:44:21,377 INFO  [io.quarkus] (main) vs-service 1.0.0-SNAPSHOT (powered by Quarkus 1.3.0.Final) started in 0.191s. Listening on: http://0.0.0.0:8080

当在同一个 docker 映像中使用 Java 启动时,它会按预期工作

[quarkus@79a141991f90 build]$ java -jar my-service-1.0.0-SNAPSHOT-runner.jar 
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-03-25 21:53:00,789 INFO  [com.che.es.eng.HealthAggregator] (main) Initializing health checks for 3 engines!
2020-03-25 21:53:01,841 INFO  [io.quarkus] (main) vs-service 1.0.0-SNAPSHOT (powered by Quarkus 1.3.0.Final) started in 3.720s. Listening on: http://0.0.0.0:8080

我尝试了什么

  • 谷歌:没有太多进展
  • 我确实发现有人提到添加 com.sun.xml.ws:rt:2.3.2,但这会导致其他错误。

任何人有什么想法让这个工作?

【问题讨论】:

  • 您似乎正在尝试使用 JAX-WS,但 Quarkus 尚不支持。必须有一个扩展才能在本机中工作。有一个 CXF 支持的功能请求:github.com/quarkusio/quarkus/issues/4005
  • 嗨,关于这个主题的任何更新?我面临着完全相同的问题。我们有一个 REST Api,它使用 jaxws 使用 SOAP 服务。一切都在 JVM 映像上工作,但使用本机映像我得到“ClassNotFoundException:com.sun.xml.internal.ws.spi.ProviderImpl”。
  • 检查这个stackoverflow.com/a/61801701/3701228,如果你通过reflection-config.json显式添加该类,它可能会起作用

标签: quarkus graalvm graalvm-native-image


【解决方案1】:

Provider com.sun.xml.internal.stream.XMLInputFactoryImpl not found 遇到了这个问题。

这似乎已在 GraalVM 20 中解决,我可以通过在 application.properties 中设置以下内容来强制 Quarkus 针对 GraalVm 20.0.0 进行构建来解决此问题:

quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-native-image:20.0.0-java11

【讨论】:

    【解决方案2】:

    我决定用 CXF 而不是 JAX-WS 来实现它并且遇到了同样的问题。解决方案是在 META-INF/services 中定义 ProviderImpl,如下所示:

    META-INF/services/javax.xml.ws.spi.Provider -> org.apache.cxf.jaxws.spi.ProviderImpl
    

    此外,为了将此文件添加到本机图像,您需要将其作为附加资源提供:

    1.在你的类路径中新建一个文件resources-config.json:

    {
      "resources": [
        {
          "pattern": "META-INF/services/.*"
        }
      ]
    }
    

    2.将文件添加到quarkus maven插件中,以便构建原生镜像

        <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus-plugin.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>native-image</goal>
                    </goals>
                    <configuration>
                        <reportErrorsAtRuntime>true</reportErrorsAtRuntime>
                        <additionalBuildArgs>-H:+AllowIncompleteClasspath,
                                            -H:ReflectionConfigurationFiles=reflection-config.json, 
    -H:ResourceConfigurationFiles=resources-config.json
                        </additionalBuildArgs>
                        <enableHttpUrlHandler>true</enableHttpUrlHandler>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    

    【讨论】:

    • 成功了吗?是否值得尝试使用 cxf 而不是 JAX WS?
    • 您好,很遗憾不是...但我建议您尝试与我相同的方法,即使您使用的是 JAX-WS,它也应该可以解决问题。
    【解决方案3】:

    您不能使用 JVM 的内部类。 实现类是“私有的”,永远不应该在依赖 JVM 实现的痛苦中使用。这是 JAVA 的基本原理之一。 您应该找出为什么要使用实现类而不是相应的接口。然后找到一个不依赖于任何实现,而只依赖于 Java API 的解决方案。

    【讨论】:

    • 我没有使用内部类,它正在被 JAX-WS 使用......
    • 你需要找出你的代码为什么加载 com.sun.xml.internal.ws.spi.ProviderImpl 从我的记忆中这个类在 JDK 11 A+JYT 之后不再存在跨度>
    【解决方案4】:

    添加这些安全和协议相关的 application.properties 为我解决了这个问题:

    quarkus.native.additional-build-args=\
      -H:EnableURLProtocols=http\\,https,\
      --enable-all-security-services,\
      -H:+JNI
    

    See the official documentation.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2020-08-02
      • 1970-01-01
      • 2020-10-25
      相关资源
      最近更新 更多