2012-05-22 2 views
2

런타임시 jar를로드하는 인터페이스를 제공하는 플러그인 시스템을 개발하려고합니다. 각 jar에는 일반적인 추상 클래스에서 확장되는 클래스가 들어 있습니다. 예를 들어공통 추상 클래스를 사용하여 jar를 동적으로로드하는 방법은 무엇입니까?

//BasicPlugin.java 
package byv; 

abstract class BasicPlugin { 
    abstract public int test(int a); 
} 

I는 서브 클래스를 구현 :

//PluginA.java 
package byv; 

import byv.BasicPlugin; 

public class PluginA extends BasicPlugin { 
    @Override 
    public int test(int a) { 
     return a + a; 
    } 
} 

상기 서브 클래스를 컴파일하고 JAR 파일 (PluginA.jar)로 포장 하였다. 이 항아리는 PluginA.class 만 포함합니다. 그리고 주 프로젝트에서 URLClassLoader를 사용하여로드합니다.

private static void loadTest() throws Exception { 
    URL url = new File("PluginA.jar").toURI().toURL(); 
    URLClassLoader ClassLoader = URLClassLoader.newInstance(new URL[] {url}); 

    Class<?> clazz = Class.forName("byv.PluginA", true, ClassLoader); 

    BasicPlugin obj = (BasicPlugin) clazz.newInstance(); 
    obj.test(2); 
} 

기본 프로젝트에서 BasicPlugin에 대한 참조가 이미 추가되었습니다. 하지만 여전히 오류가 발생했습니다 :

Exception in thread "main" java.lang.IllegalAccessError: class byv.PluginA cannot access its superclass byv.BasicPlugin 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:277) 
    at java.net.URLClassLoader.access$000(URLClassLoader.java:73) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:212) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321) 
    at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:615) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:264) 
    at byv.Main.loadTest1(Main.java:18) 
    at byv.Main.main(Main.java:11) 

이 문제를 어떻게 해결할 수 있습니까?

+0

jar 파일에 클래스를 이동하고 필요할 때 동적으로로드의 장점은 무엇입니까 : 당신의 URLClassLoader 인스턴스를 구성 할 때 –

답변

1

IllegalAccessError 때문에이 문제를 해결하기 위해 BasicPlugin을 공용으로 설정하는 것이 좋습니다. Afaik는 정의한 클래스를 패키지로 보호합니다. 따라서 다른 클래스 로더에서는 액세스 할 수 없습니다. 그게 당신이 당신의 플러그인에 필요한 것이기 때문에, 수업을 공개하는 것보다 다른 것으로 만드는 것은 말이되지 않습니다. URLClassLoader에는 부모 로더를 지정할 수있는 두 번째 생성자가 있습니다. 이 로더는 플러그인 클래스를로드하는 데 사용됩니다. 보다 복잡한 환경에서는 그 로더를 지정할 수 있습니다. 현재 귀하의 코드는 시스템 로더를 더 많이 또는 적게 사용합니다. 이는 귀하의 예에서는 괜찮지 만, 나중에 수행 할 것을 모릅니다. BasicPlugin.class.getClassLoader()는 해당 클래스의 올바른 로더를 제공합니다.

URLClassLoader ClassLoader = URLClassLoader.newInstance(new URL[] {url}, 
                 this.getClassLoader()); 
+0

간단히 BasicPlugin을 public으로 설정 한 다음 문제가 해결되었습니다. 두 번째 매개 변수는 필요하지 않습니다. – BYVoid

1

가 사용하는 클래스 로더 컨텍스트를 통과?
관련 문제