2013-05-17 8 views
1

런타임 중에 이전에로드 된 클래스를 다시로드해야하는 응용 프로그램을 작성하고 있습니다. 그 이유는 클래스가 런타임 중에 자동 생성되고 새로운 구현이 앱 작동 방식을 변경하기 때문입니다. 나는 그 클래스의 객체 하나만 생성하고 모든 종속성에서 제거했지만 상수 값을 정의하는 인터페이스는 제거하지 않았습니다. 다시로드 할 때 모든 구성원의 값을 다시 설정해도 문제가 없습니다. 나는 그것이 언제 변화하는지 정확히 알며 그것을 통제 할 수있다. 내가 가진 유일한 문제는 재 장전 자체입니다.런타임 중에 변경된 이전에로드 된 클래스를 다시로드하는 방법은 무엇입니까?

내가 읽은 바로는 ClassLoader를 사용해야합니다. 나는 그렇게하려고 노력했으나 제대로 작동시키지 못했습니다.

나는 다음과 같은 시도 :

  • 현재의 클래스 로더 (myClassObject.getClass().getClassLoader())를 얻기 및 클래스를 다시로드를 사용하여 - 작동하지 않습니다. 아마 이전 구현을 계속로드합니다.
  • 내 자신의 생성 (일명 수정에서 붙여 넣기) - 생성하는 ClassLoader가 클래스를 생성 한 클래스와 다르므로 작동하지 않습니다 (예외 : myClass를 myClass로 캐스팅 할 수 없음).
  • 수퍼 클래스의 ClassLoader를 설정하는 생성자를 만들면 아무 효과가없는 것처럼 보입니다.
  • 새로운 ClassLoader를 사용하여 myClassObject를 멤버로 갖는 클래스를 생성하면 myClassObject에 대한 ClassLoader 불일치가 해결되지만 한 수준 위로 새로운 불일치가 만들어졌습니다. 매번 getClassLoader()을 사용했는데 일치하지 않는다고 봅니다.
  • -Djava.system.class.loader=com.test.Reoader com.test.myMainClass을 기본 리로드로 추가하려고 시도했지만 컴파일러에서 오류가 발생합니다.
  • Google은 내가 이미 읽은 것과 동일한 내용으로 나를 계속 가리키고 있습니다.
  • 편집 : 인터페이스를 생성하고 구현하는 클래스를 다시로드하려고했습니다. 그것은 그것도 해결하지 못했습니다.

기본 ClassLoader를 재정의해야한다는 것을 알고 있지만 그다지 성공하지 못하는 것 같습니다.

내 클래스 로더 : 도움이 될 수 있습니다 사람에게 매우

public class Reloader extends ClassLoader { 

    public Reloader(){ 
     super(Reloader.class.getClassLoader()); 
    } 

    @Override 
    public Class<?> loadClass(String s) { 
     return findClass(s); 
    } 

    @Override 
    public Class<?> findClass(String s) { 
     try { 
      byte[] bytes = loadClassData(s); 
      return defineClass(s, bytes, 0, bytes.length); 
     } catch (IOException ioe) { 
      try { 
       return super.loadClass(s); 
      } catch (ClassNotFoundException ignore) {} 
      ioe.printStackTrace(java.lang.System.out); 
      return null; 
     } 
    } 

    private byte[] loadClassData(String className) throws IOException { 
     File f = new File("out\\production\\ManoCPU\\" + className.replaceAll("\\.", "/") + ".class"); 
     int size = (int) f.length(); 
     byte buff[] = new byte[size]; 
     FileInputStream fis = new FileInputStream(f); 
     DataInputStream dis = new DataInputStream(fis); 
     dis.readFully(buff); 
     dis.close(); 
     return buff; 
    } 
} 

감사합니다.

+0

클래스는 어떻게 자동 생성됩니까? – nakosspy

+0

나는 템플릿 파일을 읽고 자바 코드로 컴파일하는 컴파일러를 가지고있다. 템플릿 파일은 응용 프로그램 내에서 변경하고 컴파일 할 수 있습니다. – YMI

+0

매우 자주 발생합니까? 클래스를 다시 컴파일 할 수있는 횟수는 몇 번입니까? – nakosspy

답변

1

클래스는 클래스 로더 인스턴스 당 한 번만로드 할 수 있습니다. 즉, 클래스를로드 한 클래스 로더를 버리고 클래스의 업데이트 된 버전에 대해 새 클래스를 인스턴스화해야합니다.

여러 클래스 로더를 다루는 경우 여러 클래스 로더가있는 동일한 클래스를로드 할 때 동일한 클래스로 인식되지 않는다는 점도 염두에 두어야합니다.

+0

감사합니다. 나는 내가 본 모든 곳에서 똑같은 것을 읽었지 만, 나는 어떻게 그 오래된 것을 던지나요? 그것이 내가 알 수없는 것입니다.필자는 같은 클래스 일 필요가 없습니다.이 클래스는 기능이 변경된 일부 메서드를 구현하기 만하면되고 메서드가 호출 될 때마다 두 멤버 만 업데이트됩니다. – YMI

+0

여러 개의 클래스 로더가 관련된 오픈 소스 플러그인 프레임 워크의 소스 코드를 살펴볼 것을 제안합니다. 바람둥이 소스 코드도 가능할 수 있습니다. – mschenk74

관련 문제