Programing

런타임에 jar 파일을로드하는 방법

lottogame 2020. 10. 27. 07:48
반응형

런타임에 jar 파일을로드하는 방법


이 질문에 이미 답변이 있습니다.

실행 중에 새 코드 (확장)를로드 할 수있는 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 시스템을 구축하라는 요청을 받았습니다.

이 상황을 위해 만들어진 OSGi 를 기반으로하는 시스템을 원할 수도 있습니다 (또는 적어도 많이 사용).

클래스 로더를 엉망으로 만드는 것은 주로 클래스 가시성이 작동하는 방식으로 인해 정말 까다로운 작업이며 나중에 디버그하기 어려운 문제에 부딪 히고 싶지 않습니다. 예를 들어, 많은 라이브러리에서 널리 사용되는 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 및 ClassLoader를 사용하여 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;
}

참고 URL : https://stackoverflow.com/questions/194698/how-to-load-a-jar-file-at-runtime

반응형