2013-10-08 3 views
0

런타임에 클래스 경로를 동적으로 업데이트해야하는 수명이 긴 프로그램이 있습니다.Classloading을 저장, 추가, 복원 할 수 있습니까?

문제 없음 - 클래스 로더는 URLClassLoader이며 'addURL'메소드를 호출합니다. 이 모든 것이 하나의 '업데이트'반복에 효과적입니다.

나중에 '업데이트'가 도착하면 원본 클래스 경로를 복원하고 업데이트 된 항목으로 'addURL'을 호출하는 과정을 반복하고 싶습니다. 그런 다음이 과정은 며칠/주 후에 반복됩니다. 원래의 클래스 로더를 복제합니까? 내가 할 수있는 일이 가능한거야? 누군가가 이미 말할 수없는 것처럼, 나는 클래스 로더로 많은 것을하지 않고 손실이 큽니다. Java jar 파일에서 Groovy를 실행하고 있으므로 Java가 직접 실행되거나 Groovy 솔루션이 작동합니다! 아래 질문 당

편집

. 계속 올바르게 실행하려면 클래스 패스에 적용한 원래 변경 사항을 '플러시'해야합니다. 그렇지 않으면 업데이트 후에 부주의로 픽업 될 수 있습니다. 또한 클래스 패스에 여러 개의 동일한 항아리 버전을 동시에 설치하는 것에 대해 우려하고 있습니다. 예 : 첫 번째로드에서는 myJar1, myJar2 및 log4j (< - 즉 내 jar 파일 중 하나가 아닌)를 추가하고 다음 업데이트에서 myJar1 및 myJar2의 업데이트 된 버전과 myJar3 및 log4j를 추가해야 할 수도 있습니다. . 그게 더 합리적입니까?

+0

원본 클래스 경로를 복원하는 이유는 무엇입니까? –

답변

0

클래스 로더를 어떻게 복제합니까? 일반적으로 당신은하지 않습니다. 대신에 하위 로더를 만듭니다.

원래 클래스 로더에 jar를 추가하거나 변경하려고 시도하는 대신 변경하려는 jar를 포함하는 하위 클래스 로더가 필요합니다 (부모에게는 포함되어서는 안됩니다). 당신을 추가하기 위해 새로운 childloader를 생성하십시오. 복원은 기본적으로 JVM의 가비지 콜렉션에 의해 수행 된 다음 계속해서 할 수 있습니다. 그러나 기존 병을 덮어 쓰는 것은 가능하지 않을 수도 있습니다 (병이 열렸을 가능성이 있기 때문에 창에있을 수도 있음). 또는 매우 이상한 유물이 생길 수 있기 때문에 버전이있는 병으로 작업해야합니다.

프로그램 자체가 변경하려는 항아리의 클래스에 의존해야한다면, 프로그램을 변경하지 않아도되며, 그렇지 않으면 아이디어를 포기해야합니다.

어떤 이유로 복제를 계속하고 싶은데 로더가 URL에서만로드하는 일반 URLClassLoader 인 경우 (예 : GroovyClassLoader에서 작동하지 않는 경우) 리플렉션을 사용하여 ucp 필드에 액세스 할 수 있습니다 그 객체에는 필드 URL이 있습니다. 스택은 스택이며 찾고있는 정보를 포함해야합니다.

public class DynamicClassLoader extends URLClassLoader { 

    public DynamicClassLoader(ClassLoader parent, URL... urls) { 
     super(urls, parent); 
    } 

    public void addURLs(Iterable<URL> urls) { 
     for (URL url : urls) { 
      addURL(url); 
     } 
    } 

    public void resetThreadContextLoader() { 
     Thread currentThread = Thread.currentThread(); 
     currentThread.setContextClassLoader(getParent()); 
    } 
} 

내 사용 모델은 다음과 같습니다 그러나 다른 사람이 이제까지 @blackdrag 응답을 사용하여이 필요한 경우이 참고로 길을 잘못

+0

죄송합니다, 어제 나갔다. 나는 당신이 개념적으로 말한 것을 따르며 그것은 완벽하게 이해됩니다. 나는 오늘이 시간을 보냈다. 기본적으로 URLClassLoader를 확장하는 클래스의 자체 인스턴스를 만들어 클래스에로드해야한다고 생각합니다.다음으로, 범위를 벗어나게 한 다음 업데이트 된 파일 세트로 파일을 다시 만듭니다. 이것이 효과가 있다면, 그것은 내가 원하는 것입니다! – JoeG

0

인 경우 99 %에서, 경고,이 자바 클래스를 생성 그루비에서. 따라서 이것을 사용하려면 다음과 같아야합니다.

def myClassLoader = Thread.currentThread().contextClassLoader 
dynamicLoader?.resetThreadContextLoader() 
dynamicLoader = new DynamicClassLoader(myClassLoader) 
dynamicLoader.addURLs(myListOfJarURLs) 

완벽하게 작동합니다. 매우 간단합니다 - 내 Groovy 코드는 시간이 지남에 따라 반복적으로 위 네 줄을 다시 실행합니다. 이전의 dynamicLoader가 있으면 classpath가 재설정되고 jar의 업데이트 된 목록으로 즉시 수정됩니다.

관련 문제