2010-08-08 3 views
5

사용자 정의 ClassLoader를 정의하려고합니다. ContextClassLoader가 연결되지 않음

public class ExampleLoader extends ClassLoader 
{ 
    public Class<?> findClass(String name) throws ClassNotFoundException 
    { 
     System.out.println("This never gets printed"); 
     return super.findClass(name); 
    } 

    public Class<?> loadClass(String name, boolean b) 
     throws ClassNotFoundException 
    { 
     System.out.println("This never gets printed"); 
     return super.loadClass(name, b); 
    } 
} 

그리고 물론 내 코드

그것을 테스트 :

public class Tester 
{ 
    public static void main(String[] args) 
    { 
     Thread t = new FooThread(); 
     t.setContextClassLoader(new ExampleLoader()); 
     t.start(); 
    } 
} 

class FooThread extends Thread 
{ 
    public void run() 
    { 
     new RandomClass(); 
    } 
} 

문제는 내 선이 인쇄되지는 결코 것입니다. 분명히 나는 ​​뭔가를 놓치고있다.

답변

6

이것은 bug 4868493과 관련 있습니다. 여기에 관련성의 인용이다 :

불행하게도 getContextClassLoadersetContextClassLoader에 대한 설명서가 예상대로 제출자의 코드가 작동해야 결론을 이끌 수 있습니다.

그러나, 클래스 로딩의 기본 규칙이있다 - 더 클래스는 지금까지 자동으로 직접 클래스 'ClassLoader 또는 그 조상 ClassLoaders 중 하나에 의해로드 할 수 없습니다 수 "다운 스트림"입니다 클래스, 즉를로드 할 수 없습니다.

이것은 여러 곳에서 설명됩니다. 예를 들어 백서를 읽으려면 여기를 참조하십시오. http://www.javageeks.com/Papers/ClassForName/index.html 깨달음을 얻기 위해.

핵심어 포인트는 컨텍스트 클래스 로더가 Java 언어에 의해 자동으로 사용되지 않는 것으로 보입니다. 은 컨텍스트 클래스 로더를 저장하기 때문에 다른 클래스에서는 3-argument form of Class.forName과 함께 사용할 수 있습니다. Thread.getContextClassLoaderThread.setContextClassLoader 에 대한

사양

명확히해야하며, "문맥 클래스 로더 '의 의미는 명확히해야한다. 문서 버그로 다시 분류.

사양이 아직 명확하지 않습니다.

This never gets printed
+0

, 어떻게 톰캣 같은 응용 프로그램은이 일을해야합니까? 내 이해는 모든 바람둥이 webapps 공유 jvm 내에서 실행되지만 클래스를 사용할 때, 클래스 정의는 각각의 전쟁에서 비롯됩니다. 그들이 어떻게이 아이디어를 얻었는지? – Jim

+2

그들은'ClassLoader # loadClass()'를 사용합니다. 'ClassLoader' 인스턴스는이 방법으로 쓰레드에 저장되고 전달됩니다. 소스 코드를 살펴 보는 좋은 출발점은'org.apache.catalina.core.DefaultInstanceManager'입니다. – BalusC

0

보통을하는 JVM의 모든 클래스 로더가 구성됩니다 :

는이 인쇄, contradictorily, 다음

Class.forName(RandomClass.class.getName(), 
       true, 
       getContextClassLoader()).newInstance(); 

에 의해 new RandomClass()을, 당신이 처음에 원하는 작업을 대체 할 얻으려면 모든 클래스 로더 (전체 JVM을 부트 스트랩하는 원시 클래스 로더를 제외하고)는 하나의 부모를가집니다. 클래스를로드하라는 메시지가 표시되면 모든 호환 클래스 로더는 먼저 상위 클래스에로드를 위임하고 상위 클래스가 실패 할 경우에만 클래스를 정의하려고 시도합니다.

귀하의 경우에도 동일한 일이 발생하고 있습니다. "RandomClass"가로드되고, ContextClassLoader는 그 부모에게 위임합니다. 그리고 부모 클래스 로더 중 하나가 "RandomClass"를로드 할 수있었습니다 (RandomClass가 부모의 클래스 패스에 있음). 이런 이유 때문에 SOP가 나타나지 않습니다.기사 다음

참조 조금 오래된하지만 좋은 :

호기심에서

http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html?page=1

관련 문제