15

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

$ native-image -H:+TraceClassInitialization --initialize-at-run-time=org.slf4j,org.apache.log4j \
               -jar ./my-jar-with-dependencies.jar

我收到这些错误消息,例如:

错误:应该在运行时初始化的类在图像构建期间被初始化: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

4

2 回答 2

6

这些步骤对我有用。我尝试过使用 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
  • 运行它,你会看到一些类似这样的错误:
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)
  • 你看到我标记的那一行。那就是要包含的类。
  • 接下来运行带有额外参数的相同命令--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
于 2020-09-10T16:04:41.227 回答
4

如果您使用 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
于 2021-03-03T17:08:09.023 回答