native-image 无法在类路径中使用 google-auth-library-oauth2-http 构建

问题描述 投票:0回答:1

我正在尝试使用 GraalVM 的

native-image
构建一些软件。我的依赖项包括 google-auth-library-oauth2-http。即使我实际上没有使用库中的任何东西,我的构建也会失败:

➜  gv cat HelloWorld.java
class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

➜  javac HelloWorld.java && native-image -cp google-auth-library-oauth2-http-1.20.0.jar -cp . HelloWorld
...
The build process encountered an unexpected error:

> com.oracle.svm.core.util.VMError$HostedError: com.oracle.svm.core.util.UserError$UserException: Image heap writing found a class not seen during static analysis. Did a static field or an object referenced from a static field change during native image generation? For example, a lazily initialized cache could have been initialized during image generation, in which case you need to force eager initialization of the cache before static analysis or reset the cache using a field value recomputation.
class: java.util.concurrent.ConcurrentSkipListMap$Values
  reachable through:
    object: [Ljava.lang.Class;@1668bbd3  of class: java.lang.Class[]
    object: com.oracle.svm.core.code.ImageCodeInfo@1703e50d  of class: com.oracle.svm.core.code.ImageCodeInfo
    root: com.oracle.svm.core.code.ImageCodeInfo.prepareCodeInfo()

该库本身似乎附带了一些 graalvm 资源,因此作者清楚地记住了这个用例:

➜  gv unzip -l google-auth-library-oauth2-http-1.20.0.jar | grep .json
    14581  10-04-2023 00:49   META-INF/native-image/com.google.auth/google-auth-library-oauth2-http/reflect-config.json

但我不太清楚我做错了什么才能让它发挥作用。

google-oauth graalvm graalvm-native-image google-auth-library
1个回答
0
投票

检查这是否与“本机图像中的反射

”有关

Native Image 对反射有部分支持,需要提前知道反射访问的程序元素。通过

java.lang.reflect.*
检查和访问程序元素或在运行时使用
Class.forName(String)
加载类需要为这些程序元素准备额外的元数据。 (注意:这里包含带有
Class.forName(String)
的加载类,因为它与反射密切相关。)

Native Image 尝试通过静态分析来检测对 Reflection API 的调用来解析目标元素。如果分析失败,则必须使用手动配置来指定在运行时反射访问的程序元素。

错误信息显示,运行时动态使用了静态分析阶段未遇到的类,

native-image
默认无法处理。

您应该尝试提供额外的配置来帮助

native-image
理解并包含这些动态加载的类。该库确实带有 reflect-config.json
,但您可能需要扩展此配置以涵盖所有情况。

尝试修改或扩展库中的

reflect-config.json

 文件以包含动态访问的任何缺失的类或成员。
构建本机映像时,请使用
-H:ReflectionConfigurationFiles
 选项指定反射配置文件的路径。

为了将

reflect-config.json

 扩展为 
google-auth-library-oauth2-http
,您将需要识别可反射访问但现有配置中未涵盖的类和方法。您遇到的错误消息给出了提示:
java.util.concurrent.ConcurrentSkipListMap$Values

创建一个新的 JSON 文件(命名;例如,

extended-reflect-config.json

)并包含缺少的类及其方法的条目。
对于错误中提到的类,JSON 条目将是:

[ { "name": "java.util.concurrent.ConcurrentSkipListMap$Values", "allDeclaredConstructors": true, "allPublicConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true } // include other missing classes similarly ]
该配置告诉 

native-image

 包含指定类的所有构造函数和方法(声明的和公共的)。

如果现有

reflect-config.json

 中还有其他配置,您应该将它们与您的 
extended-reflect-config.json
 合并,以确保包含所有必要的配置。

使用

native-image

 构建时,请参考您的 
extended-reflect-config.json

native-image -cp google-auth-library-oauth2-http-1.20.0.jar -cp . -H:ReflectionConfigurationFiles=extended-reflect-config.json HelloWorld
该过程可能需要一些尝试和错误来识别所有必要的类和方法。

您可以在
Dmitry Chuyko 的“Spring Boot with GraalVM Native Image”中看到类似的案例研究。

© www.soinside.com 2019 - 2024. All rights reserved.