如何使用 GraalVM native-image 修复“尝试避免初始化导致初始化的类”

Sam*_*ers 12 java jar graalvm graalvm-native-image

我正在尝试从一个胖 jar 文件创建一个本地图像

$ native-image -H:+TraceClassInitialization --initialize-at-run-time=org.slf4j,org.apache.log4j \
               -jar ./my-jar-with-dependencies.jar
Run Code Online (Sandbox Code Playgroud)

我收到了如下错误消息:

错误:应该在运行时初始化的类在图像构建期间被初始化:org.apache.log4j.Level 该类被请求在构建时初始化(从命令行)。org.apache.log4j.Level 已在没有本地图像初始化检测的情况下进行初始化,并且无法跟踪堆栈跟踪。尽量避免初始化导致 org.apache.log4j.Level org.slf4j.log4j12.Log4jLoggerAdapter 初始化的类,该类在构建时(从命令行)被请求初始化。org.slf4j.log4j12.Log4jLoggerAdapter 已在没有本机图像初始化检测的情况下进行初始化,并且无法跟踪堆栈跟踪。尽量避免初始化导致 org.slf4j.log4j12.Log4jLoggerAdapter org.apache.log4j 初始化的类。在构建时(从命令行)请求类被初始化的记录器。org.apache.log4j.Logger 已在没有本地图像初始化检测的情况下进行初始化,并且无法跟踪堆栈跟踪。尽量避免初始化导致 org.apache.log4j.Logger 初始化的类

解决avoiding to initialize the class问题的途径和途径是什么?我该如何处理这些消息?

我的 graavlVM 版本是 2.0.0-java11

inm*_*yth 13

这些步骤对我有用。我尝试过使用 slf4j 和 logback、log4j2 但最终有效的是slf4j-simple。基本上我尝试包含触发初始化的特定类--initialize-at-build-time。这就是我所做的。

  • -H:+TraceClassInitialization在构建命令上添加参数,如下所示:
native-image -jar my-app.jar 
-H:IncludeResources=".*.xml|.*.conf" 
-H:+ReportUnsupportedElementsAtRuntime 
-H:+TraceClassInitialization 
-H:Name=my-app
--verbose
Run Code Online (Sandbox Code Playgroud)
  • 运行它,你会看到类似这样的错误:
Error: Classes that should be initialized at run time got initialized during image building:
 org.slf4j.simple.SimpleLogger was unintentionally initialized at build time. io.netty.channel.AbstractChannel caused initialization of this class with the following trace:
        at org.slf4j.simple.SimpleLogger.<clinit>(SimpleLogger.java) // THIS IS THE OFFENDING CLASS
        at org.slf4j.simple.SimpleLoggerFactory.<init>(SimpleLoggerFactory.java:45)
        at org.slf4j.simple.SimpleServiceProvider.initialize(SimpleServiceProvider.java:43)
Run Code Online (Sandbox Code Playgroud)
  • 你看到我标记的一行。这是要包含的类。
  • 接下来运行带有额外参数的相同命令--initialize-at-build-time=org.slf4j.simple.SimpleLogger
  • 运行。您可能需要重复上述所有步骤,因为可能会出现更多错误。如果是这样,请添加类,并用逗号分隔它们。

就我而言,最终命令如下所示

native-image -jar my-app.jar 
-H:IncludeResources=".*.xml|.*.conf" 
-H:+ReportUnsupportedElementsAtRuntime 
-H:+TraceClassInitialization 
--initialize-at-build-time=org.slf4j.simple.SimpleLogger,org.slf4j.LoggerFactory
-H:Name=my-app
--verbose
Run Code Online (Sandbox Code Playgroud)

  • 错误:非布尔选项“TraceClassInitialization”不能使用 +/- 前缀。使用 'TraceClassInitialization=&lt;value&gt;' 格式错误:使用 -H:+ReportExceptionStackTraces 打印底层异常的堆栈跟踪 (5认同)
  • 使用 -H:TraceClassInitialization=true 代替 (2认同)

Ale*_*zin 8

如果您使用 Slf4J 和 Logback,以下是要排除的类的完整列表:

--initialize-at-build-time=\
org.slf4j.impl.StaticLoggerBinder\
,org.slf4j.LoggerFactory\
,ch.qos.logback.classic.Logger\
,ch.qos.logback.core.spi.AppenderAttachableImpl\
,ch.qos.logback.core.status.StatusBase\
,ch.qos.logback.classic.Level\
,ch.qos.logback.core.status.InfoStatus\
,ch.qos.logback.classic.PatternLayout\
,ch.qos.logback.core.CoreConstants
Run Code Online (Sandbox Code Playgroud)