当前位置: 首页 > 知识库问答 >
问题:

如何用GraalVM本机映像修复“试图避免初始化导致初始化的类”

盛建德
2023-03-14

我正在尝试使用

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

我收到了这些错误信息,比如:

错误:应该在运行时初始化的类在映像构建过程中被初始化了:org.apache.log4j。在构建时(从命令行)请求初始化该类的级别。org.apache.log4j。在没有本机映像初始化仪表的情况下初始化了级别,并且无法跟踪堆栈跟踪。尝试避免初始化导致org.apache.log4j初始化的类。级别org.slf4j.log4j12。Log4jLoggerAdapter在构建时(从命令行)请求初始化该类。org.slf4j.log4j12。在没有本机映像初始化仪表的情况下初始化了Log4jLoggerAdapter,并且无法跟踪堆栈跟踪。尝试避免初始化导致初始化org.slf4j.log4j12的类。Log4jLoggerAdapterorg.apache.log4j。日志类在构建时被请求初始化(从命令行)。org.apache.log4j。日志已在没有本机映像初始化仪表的情况下初始化,堆栈跟踪无法跟踪。尝试避免初始化导致初始化org.apache.log4j的类。记录器

避免初始化类问题的方法和途径是什么?我该如何处理这些信息?

我的graavlVM版本是2.0.0-java11

共有2个答案

夔高寒
2023-03-14

以下是使用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
贡正诚
2023-03-14

这些步骤对我有用。我尝试过使用slf4j和logback,log4j2,但最终有效的是slf4j simple。基本上,我尝试在中包含触发初始化的特定类——在构建时初始化。我就是这么做的。

  • 在build命令上添加参数-H:traceClassification,如下所示:
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)
  • 您看到我标记的一行。这是要包含的类。
  • 下一步运行相同的命令,并添加额外的参数--在构建时初始化=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

 类似资料:
  • 可将PS Vita的开始画面恢复为购买时的状态。 轻触[初始化]>[初始化开始画面的图像]>[初始化]。

  • 当云联壹云的First Node部署成功后,用户可根据使用场景快速引导配置云联壹云平台。 设置管理员用户 当First Node节点部署完成后,用户在浏览器中输入First Node节点的IP地址,如提示“您的连接不是私密连接”,请单击 “高级” 按钮,并单击“继续前往x.x.x.x(不安全)”,打开云管平台控制台。 在管理员注册页面,设置管理员账号、密码,单击 “注册” 按钮,创建管理员用户。

  • 提前谢谢。 所以我试图用Maven部署JavaFX应用程序。 它给了我这个错误 我知道为什么它会给出错误。我正在使用Firebase。所以在构建时间初始化的类很少。那么我如何避免它呢? 我评论了我在我的项目中做的所有Firebase代码,并再次测试了它,然后它工作正常。但是当我再次包含Firebase时,我面临这个问题。任何帮助请

  • Initialization 初始化 Although it doesn’t look superficially very different from initialization in C or C++, initialization in Go is more powerful. Complex structures can be built during initialization a

  • 初始化是为类、结构体或者枚举准备实例的过程。这个过需要给实例里的每一个存储属性设置一个初始值并且在新实例可以使用之前执行任何其他所必须的配置或初始化。 你通过定义初始化器来实现这个初始化过程,它更像是一个用来创建特定类型新实例的特殊的方法。不同于 Objective-C 的初始化器,Swift 初始化器不返回值。这些初始化器主要的角色就是确保在第一次使用之前某类型的新实例能够正确初始化。 类类型的

  • new iSlider(DOM, DATA, OPTIONS) Name Type Description DOM dom 容器dom节点 DATA Array 数据列表 OPTIONS Object 配置项 DOM new iSlider(DOM, DATA, OPTIONS); {HTMLElement} 容器dom节点 作为第一个参数并不是必须的,会被OPTIONS.dom覆盖,但是这十分必