我已经看到在升级到log4j2之后,它无法使用java.lang.NoClassDefFoundError
加载静态嵌套类。
我有一个SingletonHolder
这样的课程
class SingletonHolder {
static class Holder {
private static final SingletonInstance INSTANCE = new SingletonInstance();
}
static public SingletonInstance getInstance() {
return INSTANCE;
}
}
引用SingletonHolder.getInstance()
时,我收到以下异常
Caused by: java.lang.NoClassDefFoundError: Could not initialize class mypkg. SingletonHolder$Holder
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:340)
at org.apache.logging.log4j.core.util.Loader.initializeClass(Loader.java:285)
at org.apache.logging.log4j.core.impl.ThrowableProxy.loadClass(ThrowableProxy.java:500)
at org.apache.logging.log4j.core.impl.ThrowableProxy.toExtendedStackTrace(ThrowableProxy.java:621)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:170)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:171)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:148)
at org.apache.logging.log4j.core.impl.Log4jLogEvent.getThrownProxy(Log4jLogEvent.java:323)
at org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.format(ExtendedThrowablePatternConverter.java:64)
at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:36)
at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:189)
at org.apache.logging.log4j.core.layout.PatternLayout.toSerializable(PatternLayout.java:53)
at org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:52)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:104)
at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:86)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:97)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:428)
at org.apache.logging.log4j.core.async.AsyncLoggerConfig.asyncCallAppenders(AsyncLoggerConfig.java:118)
at org.apache.logging.log4j.core.async.AsyncLoggerConfigHelper$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigHelper.java:222)
at org.apache.logging.log4j.core.async.AsyncLoggerConfigHelper$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigHelper.java:207)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:128)
此代码在转移到log4j2之前工作正常。
我的log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" name="app">
<Appenders>
<RollingFile name="RollingFile" fileName="app.log"
immediateFlush="false" filePattern=app.%d{yyyy-MM-dd}.%i.log">
<PatternLayout pattern="%d{ISO8601} - ${sys:ISApplicationName} ${sys:appVersion} %-5p [%t:%C{1}:%L] - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="7"/>
</RollingFile>
<RollingFile name="RollingFileAccess" fileName="access.log"
immediateFlush="false" filePattern="access.%d{yyyy-MM-dd}.%i.log">
<PatternLayout pattern="%d{ISO8601} ${sys:ISApplicationName}-${sys:appVersion} %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="7"/>
</RollingFile>
</Appenders>
<Loggers>
<AsyncLogger name="accessLogger" level="info" additivity="false">
<AppenderRef ref="RollingFileAccess"/>
</AsyncLogger>
<asyncRoot level="info" includeLocation="true" additivity="false">
<AppenderRef ref="RollingFile"/>
</asyncRoot>
</Loggers>
</Configuration>
我使用以下属性启动应用程序
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -Dlog4j.configurationFile="path_to/log4j2.xml"
答案 0 :(得分:0)
不确定这是否有所不同,但我建议您使用Log4jContextSelector
系统属性使所有记录器异步,或<AsyncRoot>
和<AsyncLogger>
配置元素,以便您可以混合异步记录器与正常记录器。我不建议你两者兼顾。因此,如果您使用Log4jContextSelector
系统属性,请使用正常的<Root>
和<Logger>
配置元素进行配置。
我注意到错误消息在包名和类名之间有一个空格:"Could not initialize class mypkg. SingletonHolder$Holder"
...这对我来说很奇怪。这可能是代码中的错误吗?或者在这里写问题时这是一个复制粘贴的错误吗?
我试图重现这个问题,但我还需要更多细节。日志如何在这里发挥作用?您是否正在记录单身实例,如下所示?
logger.info("some message with singleton {}", SingletonHolder.instance());