java.util.logging log4j_Java Util Logging重定向到Log4j2不适用于Spring Boot应用程序

我试图将所有日志记录框架重定向到Spring Boot应用程序中的Log4j2.它适用于Java Commons Logging,SLF4J和Log4j1.x.

不幸的是,Java Util Logging(JUL)重定向不起作用,因为在应用程序类路径尚未完全组装时,Plexus Launcher会使用java.util.logging.Logger.

Log4j2文档要求设置VM参数-Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager或调用System.setProperty(“ java.util.logging.manager”,“ org. apache.logging.log4j.jul.LogManager“)方法使重定向工作.它们都不起作用:

>我的应用程序代码中的System.setProperty()来不及了.一些启动代码已经对LogManager或Logger进行了一些调用,以便无法再安装Redirection-LogManager.

> VM参数也不起作用,因为在以下情况下,应用程序类路径在该时间点不可用:

对System.setProperty()的调用将被忽略,因为Java Util Logging框架已经初始化.使用VM参数时,会发生以下异常:

$mvn spring-boot:run -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

Could not load Logmanager "org.apache.logging.log4j.jul.LogManager"

java.lang.ClassNotFoundException: org.apache.logging.log4j.jul.LogManager

at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)

at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)

at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)

at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)

at java.util.logging.LogManager$1.run(LogManager.java:195)

at java.util.logging.LogManager$1.run(LogManager.java:181)

at java.security.AccessController.doPrivileged(Native Method)

at java.util.logging.LogManager.(LogManager.java:181)

at java.util.logging.Logger.demandLogger(Logger.java:448)

at java.util.logging.Logger.getLogger(Logger.java:502)

at com.google.inject.internal.util.Stopwatch.(Stopwatch.java:27)

at com.google.inject.internal.InternalInjectorCreator.(InternalInjectorCreator.java:61)

at com.google.inject.Guice.createInjector(Guice.java:96)

at com.google.inject.Guice.createInjector(Guice.java:73)

at com.google.inject.Guice.createInjector(Guice.java:62)

at org.codehaus.plexus.DefaultPlexusContainer.addPlexusInjector(DefaultPlexusContainer.java:481)

at org.codehaus.plexus.DefaultPlexusContainer.(DefaultPlexusContainer.java:206)

at org.apache.maven.cli.MavenCli.container(MavenCli.java:542)

at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:279)

at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:497)

at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)

at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)

at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)

at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

深入研究代码表明,初始化是由Guice库引起的,该库在内部使用JUL.在这种情况下,这只是对com.google.inject.internal.util.Stopwatch.< clinit>(Stopwatch.java:27)的调用.

所以问题是,有人对如何解决这个问题有想法吗?

更新2015-08-23:

从下面的建议添加配置属性< fork> true< / fork>.通过Spring boot Maven插件mvn spring-boot:run运行该应用程序.

不幸的是,当通过命令行java -Djava.util.logging.manager = org.apache.logging.log4j.jul.LogManager -jar myapp.jar运行应用程序时,它不起作用.在这种情况下,将发生以下异常:

Could not load Logmanager "org.apache.logging.log4j.jul.LogManager"

java.lang.ClassNotFoundException: org.apache.logging.log4j.jul.LogManager

at java.net.URLClassLoader.findClass(URLClassLoader.java:381)

at java.lang.ClassLoader.loadClass(ClassLoader.java:424)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)

at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

at java.util.logging.LogManager$1.run(LogManager.java:195)

at java.util.logging.LogManager$1.run(LogManager.java:181)

at java.security.AccessController.doPrivileged(Native Method)

at java.util.logging.LogManager.(LogManager.java:181)

at java.util.logging.Logger.demandLogger(Logger.java:448)

at java.util.logging.Logger.getLogger(Logger.java:502)

at org.springframework.boot.loader.Launcher.(Launcher.java:43)

at org.springframework.boot.loader.ExecutableArchiveLauncher.(ExecutableArchiveLauncher.java:48)

at org.springframework.boot.loader.ExecutableArchiveLauncher.(ExecutableArchiveLauncher.java:45)

at org.springframework.boot.loader.JarLauncher.(JarLauncher.java:30)

at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:45)

因此,不幸的是,Spring Boot Launcher也使用Java Util日志记录,从而阻止了Log4j2的JUL重定向.

我查看了org.springframework.boot.loader.Launcher类及其子类的源代码.该问题是由于在Launcher类中声明了静态logger变量引起的.该记录器似乎未由任何Launcher类使用,因此可以轻松将其删除.

问题是,是否可以完全消除对JUL的依赖关系以解决JUL重定向问题?也许通过将stderr用于启动器诊断而不是JUL?

解决方法:

您当前的方法意味着Maven和您的应用程序都将尝试使用自定义日志管理器. Maven尝试使用它会导致您看到的异常.

您可以在pom.xml中配置Spring Boot的Maven插件,为应用程序派生一个单独的JVM:

org.springframework.boot

spring-boot-maven-plugin

true

然后在应用程序的主方法中使用System.setProperty.在您的配置生效之前,分叉一个单独的JVM可以防止Maven自己的日志混乱.

标签:spring-boot,spring,java

来源: https://codeday.me/bug/20191119/2039197.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值