Ton*_*ony 23 java logback graalvm graalvm-native-image
我正在使用当前版本的社区版:GraalVM/native-image 22.1.0
我的项目依赖于日志框架 logback (版本 1.2.3)
如果我想用 graalVM 编译我的“一体式”jar,本机映像会抱怨:
错误:java.util.concurrent.ExecutionException:com.oracle.graal.pointsto.constraints.UnsupportedFeatureException:映像堆中不允许存在 ch.qos.logback.classic.Logger 的实例,因为此类应在映像运行时初始化。要查看该对象是如何实例化的,请使用 --trace-object-instantiation=ch.qos.logback.classic.Logger。
我尝试了许多不同的设置排列,例如--initialize-at-run-time=\<complete list of logback classes\> 和--initialize-at-run-time
我尝试使用以下命令生成反射配置文件
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar build/myjar-all.jar
并将其添加到配置文件中
-H:ReflectionConfigurationFiles=reflect-config.json
但没有成功。总是收到与 logback 相关的不同错误消息。
所以我的问题是:
有人之前用 graalvm 成功编译过 logback 吗?
Tha*_*Van 26
简短的回答 - 您应该ch.qos.logback添加--initialize-at-build-time:
--initialize-at-build-time=ch.qos.logback
Run Code Online (Sandbox Code Playgroud)
有关详细信息,我想发布我为logback使用 GraalVM 所做的工作。
在该build.gradle文件中,我添加了有关在构建时、运行时应包含哪些内容的说明,以及包含反射配置的文件路径:
graalvmNative {
binaries {
all {
resources.autodetect()
}
main {
imageName.set('app')
buildArgs.add('--verbose')
buildArgs.add('--add-opens=java.base/java.nio=ALL-UNNAMED')
buildArgs.add('--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED')
buildArgs.add('--add-opens=java.base/jdk.internal.ref=ALL-UNNAMED')
buildArgs.add('--trace-class-initialization=ch.qos.logback.classic.Logger')
buildArgs.add('--trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker')
buildArgs.add('--initialize-at-build-time=org.slf4j.LoggerFactory,ch.qos.logback')
buildArgs.add('--initialize-at-run-time=io.netty')
}
}
}
nativeBuild {
buildArgs('-H:ReflectionConfigurationFiles=../../../src/main/resources/reflection-config.json')
}
Run Code Online (Sandbox Code Playgroud)
这是文件的内容reflection-config.json:
[
{
"name": "ch.qos.logback.classic.AsyncAppender",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.pattern.DateConverter",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.pattern.LevelConverter",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.pattern.LineSeparatorConverter",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.pattern.LoggerConverter",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.pattern.MessageConverter",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.classic.pattern.ThreadConverter",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.core.ConsoleAppender",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
},
{
"name": "ch.qos.logback.core.FileAppender",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredClasses": true,
"allPublicClasses": true
}
]
Run Code Online (Sandbox Code Playgroud)
我使用这个logback.xml文件:
<configuration scan="true" scanPeriod="150 seconds">
<property name="LOG_DIR" value="logs" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender" target="System.out">
<encoder>
<charset>UTF-8</charset>
<pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC} {%thread} [%-5level] %logger{0} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOG_DIR}/app.log</file>
<encoder>
<charset>UTF-8</charset>
<pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC} {%thread} [%-5level] %logger - %msg%n</pattern>
</encoder>
</appender>
<appender name="ASYNC_CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold> <!-- default 20, means drop lower event when has 20% capacity remaining -->
<appender-ref ref="CONSOLE" />
<queueSize>1024</queueSize> <!-- default 256 -->
<includeCallerData>false</includeCallerData> <!-- default false -->
<neverBlock>false</neverBlock> <!-- default false, set to true to cause the Appender not block the application and just drop the messages -->
</appender>
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold> <!-- default 20, means drop lower event when has 20% capacity remaining -->
<appender-ref ref="FILE" />
<queueSize>1024</queueSize> <!-- default 256 -->
<includeCallerData>false</includeCallerData> <!-- default false -->
<neverBlock>false</neverBlock> <!-- default false, set to true to cause the Appender not block the application and just drop the messages -->
</appender>
<root level="all">
<appender-ref ref="ASYNC_CONSOLE" />
<appender-ref ref="ASYNC_FILE" />
</root>
</configuration>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6681 次 |
| 最近记录: |