문제

이 질문은 이미 여기에 답이 있습니다.

실행 중에 새 코드 (확장)를로드 할 수있는 Java 시스템을 구축하라는 요청을 받았습니다. 코드가 실행되는 동안 JAR 파일을 다시로드하려면 어떻게해야합니까? 또는 새 항아리를 어떻게로드합니까?

분명히, 지속적인 업 타임이 중요하기 때문에, 나는 기존 클래스를 다시로드 할 수있는 능력을 추가하고 싶습니다 (너무 복잡하지 않은 경우).

내가 찾아야 할 것은 무엇입니까? (런타임에서 클래스 재 장전에 관한 두 가지 질문으로 생각하고, 다른 하나는 새 클래스 추가에 관한 것입니다).

도움이 되었습니까?

해결책

기존 데이터로 기존 클래스를 다시로드하면 문제가 발생할 수 있습니다.

새 코드를 비교적 쉽게 새 클래스 로더에로드 할 수 있습니다.

ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { yourURL },
    getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();

더 이상 사용되지 않는 클래스 로더는 쓰레기를 수집 할 수 있습니다 (주제 누수가없는 한, Threadlocal, JDBC 드라이버를 사용하는 경우가 종종 있지 않습니다. java.beans, 등).

객체 데이터를 유지하려면 직렬화와 같은 지속 메커니즘 또는 익숙한 것이 무엇이든 제안합니다.

물론 디버깅 시스템은 더 멋진 일을 할 수 있지만 더 해킹되고 신뢰성이 떨어집니다.

클래스 로더에 새로운 클래스를 추가 할 수 있습니다. 예를 들어, 사용 URLClassLoader.addURL. 그러나 클래스가로드되지 않으면 (예를 들어 추가하지 않았기 때문에) 해당 클래스 로더 인스턴스에로드되지 않습니다.

다른 팁

이것은 나를 위해 작동합니다 :

File file  = new File("c:\\myjar.jar");

URL url = file.toURL();  
URL[] urls = new URL[]{url};

ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("com.mypackage.myclass");

실행 중에 새 코드를로드 할 수있는 Java 시스템을 구축하라는 요청을 받았습니다.

시스템을 기반으로하고 싶을 수도 있습니다 오지 (또는 적어도 많은 것을 가져 가라)는이 상황을 정확히 위해 만들어졌다.

클래스 로더를 엉망으로 만드는 것은 실제로 까다로운 비즈니스입니다. 대부분 클래스 가시성이 작동하는 방식 때문이며 나중에 버그가 어려운 문제를 해결하고 싶지 않습니다. 예를 들어, class.forname (), 많은 라이브러리에서 널리 사용되는 것은 조각난 클래스 로더 공간에서 너무 잘 작동하지 않습니다.

나는 약간 검색 하고이 코드를 찾았습니다 여기:

File file = getJarFileToLoadFrom();   
String lcStr = getNameOfClassToLoad();   
URL jarfile = new URL("jar", "","file:" + file.getAbsolutePath()+"!/");    
URLClassLoader cl = URLClassLoader.newInstance(new URL[] {jarfile });   
Class loadedClass = cl.loadClass(lcStr);   

누구 든지이 접근법에 관한 의견/의견/답변을 공유 할 수 있습니까?

org.openide.util.lookup 및 클래스 로더를 사용하여 여기에 표시된대로 JAR 플러그인을 동적으로로드하십시오.

public LoadEngine() {
    Lookup ocrengineLookup;
    Collection<OCREngine> ocrengines;
    Template ocrengineTemplate;
    Result ocrengineResults;
    try {
        //ocrengineLookup = Lookup.getDefault(); this only load OCREngine in classpath of  application
        ocrengineLookup = Lookups.metaInfServices(getClassLoaderForExtraModule());//this load the OCREngine in the extra module as well
        ocrengineTemplate = new Template(OCREngine.class);
        ocrengineResults = ocrengineLookup.lookup(ocrengineTemplate); 
        ocrengines = ocrengineResults.allInstances();//all OCREngines must implement the defined interface in OCREngine. Reference to guideline of implement org.openide.util.Lookup for more information

    } catch (Exception ex) {
    }
}

public ClassLoader getClassLoaderForExtraModule() throws IOException {

    List<URL> urls = new ArrayList<URL>(5);
    //foreach( filepath: external file *.JAR) with each external file *.JAR, do as follows
    File jar = new File(filepath);
    JarFile jf = new JarFile(jar);
    urls.add(jar.toURI().toURL());
    Manifest mf = jf.getManifest(); // If the jar has a class-path in it's manifest add it's entries
    if (mf
            != null) {
        String cp =
                mf.getMainAttributes().getValue("class-path");
        if (cp
                != null) {
            for (String cpe : cp.split("\\s+")) {
                File lib =
                        new File(jar.getParentFile(), cpe);
                urls.add(lib.toURI().toURL());
            }
        }
    }
    ClassLoader cl = ClassLoader.getSystemClassLoader();
    if (urls.size() > 0) {
        cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), ClassLoader.getSystemClassLoader());
    }
    return cl;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top