2014-09-15 1 views
0

log4j2로 업그레이드 한 후 정적 중첩 클래스를 java.lang.NoClassDefFoundError으로로드하지 못했습니다. Log4j2 : NoClassDefFoundError : 정적 중첩 클래스

나는이

class SingletonHolder { 
    static class Holder { 
    private static final SingletonInstance INSTANCE = new SingletonInstance(); 
    } 

    static public SingletonInstance getInstance() { 
    return INSTANCE; 
    } 
} 

SingletonHolder.getInstance()를 참조, 나는이 코드는 log4j2로 이동하기 전에 잘 작동했다

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) 

다음과 같은 예외를 얻을이 같은 SingletonHolder 클래스입니다.

내 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

이 문제를 해결하기 위해 클린/빌드 작업을 수행했다고 가정 할 수 있습니까? 귀하의 신청서는 어떻게 포장됩니까? – BadZen

+0

@BadZen 예. 빌드가 정리되고 배포 zip이 생성됩니다. 그것의 아무도는 변화하지 않았다. 유일한 변화는 log4j2로 이동하는 것입니다. – Prasanna

+0

log4j2를 클래스 경로의 등록 정보 파일에서 초기화 하시겠습니까? 아니면 수동으로 등록 하시겠습니까? 그리고, 이것은 컨테이너 내에서 실행되고 있습니까, 그렇지 않으면 독자적인 ClassLoader()를 구현합니까? – BadZen

답변

0

확실하지 않음 다음과 같은 속성을 사용하여 응용 프로그램을 시작,하지만 난 당신이 Log4jContextSelector 시스템 속성 중 하나를 사용하는 것이 좋습니다 모든 로거를 비동기로 만들거나 <AsyncRoot><AsyncLogger> 구성 요소를 사용하여 비표준 로거와 일반 로거를 혼합 할 수 있습니다. 나는 네가 그 두 가지를하는 것을 추천하지 않는다. 따라서 Log4jContextSelector 시스템 속성을 사용하는 경우 일반 <Root><Logger> 구성 요소로 구성하십시오.

오류 메시지에 패키지 이름과 클래스 이름 사이에 공백이있는 것으로 나타났습니다. "Could not initialize class mypkg. SingletonHolder$Holder" ... 이것은 이상합니다. 이것은 코드의 버그 일 수 있습니까? 또는 여기에 질문을 쓸 때 복사하여 붙여 넣기 실수입니까?

문제를 재현하려고하지만 자세한 내용이 필요합니다. 로깅은 어떻게 작동합니까? 아래처럼 싱글 톤 인스턴스를 로깅하고 있습니까?

logger.info("some message with singleton {}", SingletonHolder.instance());