2

我正在尝试为我的 GraalVM 编译的应用程序使用的 logback 使用 groovy 配置文件。

运行它并正常编译时,一切都很好,但是当我尝试针对 Graal 进行编译时,我遇到了一些我无法理解如何解决的问题。

因此,在没有任何特定配置传递给 Graal 的情况下,我在编译期间收到以下错误:

Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of net.logstash.logback.encoder.LogstashEncoder are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized by the io.micr
onaut.runtime.Micronaut class initializer with a trace: 
        at net.logstash.logback.encoder.LogstashEncoder.<init>(LogstashEncoder.java:27)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
        at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:74)
        at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1732)
        at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1556)

我尝试了在构建期间允许初始化类的非常懒惰的方法,方法是这样做:

--initialize-at-build-time=net.logstash.logback.encoder.LogstashEncoder

这只会导致其他各种与 logstash 相关的类需要此选项,因此我继续为整个包添加了一条规则,如下所示:

--initialize-at-build-time=net.logstash.logback

这并没有解决问题,而是在编译过程中导致以下错误:

com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
 ch.qos.logback.classic.gaffer.GafferConfigurator the class was requested to be initialized at build time (from the command line). ch.qos.logback.classic.gaffer.GafferConfigurator has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. Try avoiding to initialize the class that caused initialization of ch.qos.logback.classic.gaffer.GafferConfiguratorgroovy.lang.GroovySystem the class was requested to be initialized at build time (from the command line). io.micronaut.runtime.Micronaut caused initialization of this class with the following trace:
        at ch.qos.logback.classic.gaffer.GafferConfigurator.$getStaticMetaClass(GafferConfigurator.groovy)
        at ch.qos.logback.classic.gaffer.GafferConfigurator.<init>(GafferConfigurator.groovy)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at ch.qos.logback.classic.gaffer.GafferUtil.newGafferConfiguratorInstance(GafferUtil.java:52)
        at ch.qos.logback.classic.gaffer.GafferUtil.runGafferConfiguratorOn(GafferUtil.java:41)
        at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:67)
        at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:150)
        at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
        at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
        at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
        at io.micronaut.runtime.Micronaut.<clinit>(Micronaut.java:46)

我尝试了有关在构建或运行时允许和禁止初始化的各种规则排列,但没有一个起作用。

所以我的问题是,我应该如何克服这个问题?我试图找出导致初始化的类,但我现在无法这样做。

有没有人设法让 logback 使用 groovy 配置文件并成功编译成 GraalVM 映像?

4

1 回答 1

1

由于 Groovy 的动态性,很难在 GraalVM nativeimage 上运行(但并非不可能)。我建议您通过跟踪代理运行应用程序,并查看需要什么反射配置才能使您的logback.groovy文件正常运行。

将应用程序构建到 JAR 中并使用以下命令运行应用程序:

java -agentlib:native-image-agent=config-output-dir=META-INF/native-image -jar build/myjar-all.jar

然后查看生成的reflect-config.json文件以获取与配置相关的条目logback并将其包含在您的配置中。

或者,您可以通过使用来避免麻烦logback.xml

于 2019-10-15T10:21:30.913 回答