2009-12-29 4 views
13

저는 Java의 초보자이며 클래스 로더의 개념을 이해하기 시작했습니다. 지금은 스레드 컨텍스트 클래스 로더의 사용과 관련하여 log4j에 몇 가지 문제가 있습니다.log4j와 쓰레드 컨텍스트 클래스 로더

나는 다음과 같은 오류가 받고 있어요 : 구성되어 초기화 URLClassLoader의 # 1에 일부 클래스는,이 클래스의 log4j를 사용하여로드 : A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable. The class "org.apache.log4j.Appender" was loaded by [[email protected]] whereas object of type "org.apache.log4j.ConsoleAppender" was loaded by [[email protected]]. Could not instantiate appender named "CONSOLE".

내 응용 프로그램은 대략 이런 식으로 작동합니다. 나중에 URLClassLoader # 2가 생성되고 (부모 인 URLClassLoader # 1을 가짐) 더 많은 클래스를로드합니다.이 클래스는 log4j도 사용합니다. URLClassLoader # 2를 사용하여 이러한 클래스를로드하면 위의 오류 메시지가 나타납니다 (동일한 문제가 두 개 더 있음).

내가 한 현재의 해결 방법은 문제가있는 클래스를 로딩하고, 이후에 이전에 재설정하기 전에 URLClassLoader의 # 2 현재 쓰레드 컨텍스트 클래스 로더를 설정 :이 작동하는 동안

ClassLoader urlClassLoader; // this is URLClassLoader #2 
Thread thread = Thread.currentThread(); 
ClassLoader loader = thread.getContextClassLoader(); 
thread.setContextClassLoader(urlClassLoader); 
try { 
    urlClassLoader.loadClass(...) 
} finally { 
    thread.setContextClassLoader(loader); 
} 

, 나는 아니다 그것이 올바른 접근 방법인지 확인하십시오.

이 문제에 대한 통찰력은 인정 될 것입니다. 또한 log4j가 스레드 컨텍스트 클래스 로더를 엉망으로 만들어 버리는 이유는 무엇입니까? 왜 스레드 로더를 사용하는 대신 클래스 로더에 전달하고 싶지 않을 때 디폴트 로더를 사용하게할까요?

+0

내 인생을 당신의 질문과 함께 저장했는데 비슷한 문제로 3 일 동안 갇혔다! 나는 "thread.setContextClassLoader"를 설정하지 않았다. 당신이 자바에 초보자 였음에도 불구하고 정말 멋져요! –

답변

15

log4j (및 Apache Commons Logging 라이브러리)의 주요 문제점을 발견 한 것 같습니다. 즉, 사용중인 올바른 클래스 로더를 발견하고 상호 작용하는 데 엄청나게 힘든 시간을 보냈습니다. 예제가있는 매우 밀집한 설명이 있습니다. here; take-home 메시지는 새로운 로깅 프레임 워크 SLF4J의 주된 추진력 중 하나가 이러한 문제를 완전히 없애는 것이 었습니다. 당신은 그것을 안으로 교환하고 당신의 인생이 더 쉽게 만들어 졌는지보기를 원할 것입니다.

+0

이 시점에서 다른 것을 사용하는 것이 가능한지 확실하지 않습니다. 이 log4j 문제를 해결하는 방법은 무엇입니까? –

+1

정직하게 말하면, 지금은 log4j와 Apache Commons Logging을 조심스럽게 피하는 것이 좋지 않기 때문에 말할 수는 없습니다. 실제로 SLF4J로 마이그레이션 할 수 있어야합니다 - http://www.slf4j.org/legacy.html에서 코드가 여전히 log4j를 호출 할 수있게 해주는 "브리지 어댑터"와 함께 제공되는 SLF4J에 대한 정보는 http://www.slf4j.org/legacy.html을 참고하십시오. SLF4J가 이러한 호출을 가로 채도록하십시오. 이렇게하면 새로운 코드에서 SLF4J를 기본적으로 사용할 수 있으며 기존 log4j 활용 코드를 SLF4J로 마이그레이션 할 수 있습니다. – delfuego

+0

Log4j 및 JCL을 피하기위한 힌트는 +1. 그것들은 log4j와 jcl을위한 호환성 레이어를 가지고있는 SLF4j로 대체되었습니다. 우리는 정확히 그 이유로 모든 프로젝트에서이를 수행했습니다. – mhaller