自定义 log4j 插件和 Spring 启动
Custom log4j plugin and Spring Boot
我有一个要使用的自定义 log4j 布局插件。当 IntelliJ 中的 运行 或 ./gradlew bootRun
时,插件工作正常。使用 ./gradlew bootJar
构建引导 jar 不会。
启用 -Dlog4j.debug=true
表明在 IntelliJ 和 bootRun
中使用 sun.misc.Launcher$AppClassLoader,而 jar 使用 org.springframework.boot.loader.LaunchedURLClassLoader.
在日志中挖掘从工作中揭示了以下内容:
INFO StatusLogger Scanning for classes in '/home/rohdef/.m2/repository/dk/rohdef/logging/log4j/0.4.5-SNAPSHOT/log4j-0.4.5-SNAPSHOT.jar' matching criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.CustomLog4jLayout matches criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.context.Log4jDiagnosticContext matches criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.CustomLog4jLayout matches criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.CustomLog4jLayout$Builder matches criteria annotated with @Plugin
DEBUG StatusLogger Took 0.009241 seconds to load 1 plugins from package dk.enettet.rohdef.log4j
DEBUG StatusLogger PluginManager 'Core' found 118 plugins
而 jar 日志:
INFO StatusLogger Scanning for classes in '/home/rohdef/git/foo-backend/foo-0.0.1-SNAPSHOT.jar' matching criteria annotated with @Plugin
DEBUG StatusLogger Took 0.158622 seconds to load 0 plugins from package dk.rohdef.logging.log4j
DEBUG StatusLogger PluginManager 'Core' found 117 plugins
log4j-0.4.5-SNAPSHOT.jar
正如预期的那样在 foo-0.0.1-SNAPSHOT.jar
内。
这让我怀疑LaunchedURLClassLoader 的方式是错误的来源。我说得对吗?如果是这样,这是一个错误还是我用错了?如何让我的插件工作?
来自 gitter 的 Andy Wilkinson 提供了答案:
在我看来,Log4j 正在对它在类路径上找到的 jar 文件的结构做出假设,这些假设不适用于使用嵌套在 BOOT-INF/lib
.[=14 中的 jar 的胖 jar =]
您可以使用 requiresUnpack
以便 fat jar 自动解压缩您的 log4j-0.4.5-SNAPSHOT.jar
以便它可以直接在 Log4j 应该能够扫描它的文件系统上使用:https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-configuring-unpacking
我有一个要使用的自定义 log4j 布局插件。当 IntelliJ 中的 运行 或 ./gradlew bootRun
时,插件工作正常。使用 ./gradlew bootJar
构建引导 jar 不会。
启用 -Dlog4j.debug=true
表明在 IntelliJ 和 bootRun
中使用 sun.misc.Launcher$AppClassLoader,而 jar 使用 org.springframework.boot.loader.LaunchedURLClassLoader.
在日志中挖掘从工作中揭示了以下内容:
INFO StatusLogger Scanning for classes in '/home/rohdef/.m2/repository/dk/rohdef/logging/log4j/0.4.5-SNAPSHOT/log4j-0.4.5-SNAPSHOT.jar' matching criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.CustomLog4jLayout matches criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.context.Log4jDiagnosticContext matches criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.CustomLog4jLayout matches criteria annotated with @Plugin
DEBUG StatusLogger Checking to see if class dk.rohdef.logging.log4j.CustomLog4jLayout$Builder matches criteria annotated with @Plugin
DEBUG StatusLogger Took 0.009241 seconds to load 1 plugins from package dk.enettet.rohdef.log4j
DEBUG StatusLogger PluginManager 'Core' found 118 plugins
而 jar 日志:
INFO StatusLogger Scanning for classes in '/home/rohdef/git/foo-backend/foo-0.0.1-SNAPSHOT.jar' matching criteria annotated with @Plugin
DEBUG StatusLogger Took 0.158622 seconds to load 0 plugins from package dk.rohdef.logging.log4j
DEBUG StatusLogger PluginManager 'Core' found 117 plugins
log4j-0.4.5-SNAPSHOT.jar
正如预期的那样在 foo-0.0.1-SNAPSHOT.jar
内。
这让我怀疑LaunchedURLClassLoader 的方式是错误的来源。我说得对吗?如果是这样,这是一个错误还是我用错了?如何让我的插件工作?
来自 gitter 的 Andy Wilkinson 提供了答案:
在我看来,Log4j 正在对它在类路径上找到的 jar 文件的结构做出假设,这些假设不适用于使用嵌套在 BOOT-INF/lib
.[=14 中的 jar 的胖 jar =]
您可以使用 requiresUnpack
以便 fat jar 自动解压缩您的 log4j-0.4.5-SNAPSHOT.jar
以便它可以直接在 Log4j 应该能够扫描它的文件系统上使用:https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-configuring-unpacking