2011-08-17 3 views
1

학술 목적을위한 HTTP WebServer 프로젝트의 일부로 웹 응용 프로그램 클래스에 대한 고유 한 사용자 정의 클래스 로더를 작성하려고하지만 보이지 않습니다. 그것을 올바르게하기.Java - 사용자 정의 ClassLoader - 클래스 파일 전체 경로를 사용하여 클래스를로드하려고합니다.

일반적으로 웹 응용 프로그램은 자체 폴더에 있으며 웹 응용 프로그램의 ".class"파일은 직접적인 상위 폴더 이름과 같습니다. (예 : Web1/Web1.class). 나는 defineClass() 방법에 도달 할 때까지 아래의 코드는 잘 작동하고 다음과 같은 예외로 날을 던졌습니다 :

java.io.FileNotFoundException: C:\inetpub\javawwwroot\WebApps\java\lang\Object\.Object.class (The system cannot find the path specified)

그것은 C:\inetpub\javawwwroot\WebApps\ 부분은 아래의 코드에서 m_WebAppsFullPath 변수를 동일 언급 할 가치가있다. 또한

,

InputStream in = getResourceAsStream(clsFile);

대신 InputStream in = new FileInputStream(clsFile);

내가 널 반환 값을 얻을 ...이

UPDATE 사용하려고 할 때 : 즉, 어떻게로드 할 수 있습니다 "CLASSPATH"에 없거나 내 프로젝트의 패키지에있는 특정 클래스?

protected synchronized Class loadClass(String className, boolean resolve) 
          throws ClassNotFoundException 
{ 
    log("Loading class: " + className + ", resolve: " + resolve); 

    // 1. is this class already loaded? 
    Class cls = findLoadedClass(className); 
    if (cls != null) 
    { 
     return cls; 
    } 

    // 2. get class file name from class name 
    String classRelativePath = className.replace('.', '/'); 
    String classFileName = 
     ((className.lastIndexOf('.') != -1) ? className.substring(className.lastIndexOf('.')) : className) + ".class"; 

    String clsFile = m_WebAppsFullPath + "\\" + classRelativePath + "\\" + classFileName; 

    // 3. get bytes for class 
    byte[] classBytes = null; 
    try 
    { 
     //InputStream in = getResourceAsStream(clsFile); 
     InputStream in = new FileInputStream(clsFile); 
     byte[] buffer = new byte[BUFFER_SIZE]; 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     int n = -1; 
     while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) { 
      out.write(buffer, 0, n); 
     } 
     classBytes = out.toByteArray(); 
    } 
    catch (IOException e) { 
     log("ERROR loading class file: " + e); 
    } 

    if (classBytes == null) { 
     throw new ClassNotFoundException("Cannot load class: " + className); 
    } 

    // 4. turn the byte array into a Class 
    try { 
     cls = defineClass(className, classBytes, 0, classBytes.length); 
     if (resolve) { 
      resolveClass(cls); 
     } 
    } 
    catch (SecurityException e) { 
     // loading core java classes such as java.lang.String 
     // is prohibited, throws java.lang.SecurityException. 
     // delegate to parent if not allowed to load class 
     cls = super.loadClass(className, resolve); 
    } 

    return cls; 
} 

어떻게 작동시킬 수 있습니까?

감사합니다.

+0

전체 예외 스택 추적 –

+0

'... \ Object \ .Object.class' 물론'... \ Object.class'가 필요 없습니다. – vickirk

+0

아니요, Web1이라는 클래스를로드하려고합니다.C : \ inetpub \ javawwwroot \ WebApps \ Web1 \ Web1.class 다음과 같은 디렉토리가 없습니다. C : \ inetpub \ javawwwroot \ WebApps \ java \ lang \ –

답변

4

현재 사용자는 자신의 클래스 로더를 통해 사용자 정의 클래스를로드하려고 할뿐만 아니라 해당 클래스가 사용하는 모든 시스템 클 래스도로드하려고합니다. 예 : java.lang.Object, 여기에 문제가 있습니다.

일반적으로 Java의 클래스 로더는 체인화되어 있습니다. 즉, 클래스 로더가 다른 클래스 (시스템 클래스 로더)에 의해 정의되었다는 의미입니다. 따라서 loadClass 메서드를 직접 덮어 쓰지 말고 두 메서드 'findClass (String) : Class 및 loadClassData (String) : Class를 덮어 쓰는 것이 좋습니다.

클래스 로더 클래스는 클래스 및 자원을 검색하기 위해 위임 모델을 사용하여 여기에

는 클래스 로더 클래스의 자바 독에서 excerp입니다. ClassLoader의 각 인스턴스에는 부모 클래스 로더가 연결된 이 있습니다. 클래스 또는 리소스를 찾도록 요청되면 ClassLoader 인스턴스는 클래스 또는 리소스 자체를 찾으려고 시도하기 전에 클래스 또는 리소스에 대한 검색을 상위 클래스 로더에 위임합니다. 가상 머신의 빌트인 클래스 로더 는 "부트 스트랩 클래스 로더"라고 불리며, 그 자체는 부모를 가지지 않지만 은 ClassLoader 인스턴스의 부모 역할을 할 수 있습니다.

는 같은 자바 독은 심지어 예를 나열, 사용자 정의 제대로 클래스 로더 정의하는 방법 : 당신이 그 부분을 읽어보십시오 생각

class NetworkClassLoader extends ClassLoader { 
    String host; 
    int port; 

    public Class findClass(String name) { 
     byte[] b = loadClassData(name); 
     return defineClass(name, b, 0, b.length); 
    } 

    private byte[] loadClassData(String name) { 
     // load the class data from the connection 
      . . . 
    } 
} 

을 : Javadoc for ClassLoader 당신이 보여줄 수 있다면 도움이 될

+0

까마귀가 맞습니다. 사용자 정의 논리를 찾으려면 findClass 메소드에 넣어야합니다. –

+0

하지만 전체 Java ClassLoaders 계층을 기반으로 최상위 클래스 클래스 로더의 Object 클래스를 먼저로드하면 안됩니까? 그런 다음 실패하면 내 자신의 사용자 정의 클래스 로더를 사용하여로드하려고합니까? –

+0

예. 그러나 loadClass 대신 findClass 및 loadClassData에 코드를 추가하면 해당 비헤이비어가 이미 처리됩니다. ;) –

관련 문제