Graalvm aot中logback的处理和自动重载
官方说明:Logging in Native Image (graalvm.org)
我使用graalvm-community-jdk-21.0.1_windows-x64_bin.zip,解压后配置好JAVA_HOME和PATH,安装 C++,就可以直接使用,不需要复杂的匹配过程
日志这一块卡了很长时间,最后的方法是在application.yml中启用日志
然后编译时,会自动根据XML中的内容去判断反射的类,生成相关的引用信息,不需要自己在编译参数中增加内容
@@@code
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> <configuration> <skip>false</skip> <buildArgs> --no-fallback <!-- --initialize-at-build-time=io.netty--> <!-- --initialize-at-run-time=org.apache.logging.log4j.spi.Provider--> <!-- --initialize-at-build-time=ch.qos.logback--> <!-- --initialize-at-build-time=org.springframework.util.unit.DataSize--> <!-- --initialize-at-build-time=org.slf4j.MDC--> <!-- --initialize-at-build-time=ch.qos.logback.classic.Level--> <!-- --initialize-at-build-time=ch.qos.logback.classic.Logger--> <!-- --initialize-at-build-time=ch.qos.logback.core.util.StatusPrinter--> <!-- --initialize-at-build-time=ch.qos.logback.core.status.StatusBase--> <!-- --initialize-at-build-time=ch.qos.logback.core.status.InfoStatus--> <!-- --initialize-at-build-time=ch.qos.logback.core.spi.AppenderAttachableImpl--> <!-- --initialize-at-build-time=org.slf4j.LoggerFactory--> <!-- --initialize-at-build-time=ch.qos.logback.core.util.Loader--> <!-- --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder--> <!-- --initialize-at-build-time=ch.qos.logback.classic.spi.ThrowableProxy--> <!-- --initialize-at-build-time=ch.qos.logback.core.CoreConstants--> --report-unsupported-elements-at-runtime --allow-incomplete-classpath -H:+ReportExceptionStackTraces </buildArgs> </configuration> </plugin>
这种方法得到的EXE,logback已经提前编译并匹配好了,可以直接使用,但会发现不会再接受外部指定的logging.config了,即使修改了logback-spring.xml中的内容,也不会生效。
为了再次更新配置,并使用scan功能,需要使用代码重新配置一次(配置可从application.yml中直接取,也可以使用-Dlogging.config=file:../config/logback-spring.xml重新指定位置,
@@@code@java@
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory(); //AOT不支持scan autoload ,并且在编译时确定了日志等级,也不支持外部文件覆盖配置,需要手工判断文件并重新载入 if (!reloaded.get()) { loggerContext.reset(); JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(loggerContext); configurator.doConfigure(new URL(env.getProperty("logging.config"))); log.warn("重新加载日志配置{}", env.getProperty("logging.config")); reloaded.set(true); } ch.qos.logback.classic.Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME); if (rootLogger != null) System. out . println("root level=" + rootLogger.getLevel());