我在开发系统的一个插件功能,就是提供一个接口,动态加载插件jar,然后执行。所有的插件继承于抽象类BasicPlugin,例如我实现了一个PluginA,在主程序中动态加载://BasicPlugin.java
package byv;abstract class BasicPlugin {
abstract public int test(int a);
}//PluginA.java
package byv;import byv.BasicPlugin;public class PluginA extends BasicPlugin {
@Override
public int test(int a) {
return a + a;
}
}//主程序
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);
}
其中PluginA.java被打包成了PluginA.jar,里面仅仅包含PluginA.class,不包含BasicPlugin.class。这时运行会出现这样的错误:
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)
但如果我把BasicPlugin.class也放入其中,类型转换会失败,两个BasicPlugin会被识别为不同的东西。怎么办??
package byv;abstract class BasicPlugin {
abstract public int test(int a);
}//PluginA.java
package byv;import byv.BasicPlugin;public class PluginA extends BasicPlugin {
@Override
public int test(int a) {
return a + a;
}
}//主程序
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);
}
其中PluginA.java被打包成了PluginA.jar,里面仅仅包含PluginA.class,不包含BasicPlugin.class。这时运行会出现这样的错误:
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)
但如果我把BasicPlugin.class也放入其中,类型转换会失败,两个BasicPlugin会被识别为不同的东西。怎么办??
public class Test {
public static void main(String... args) {
Class<?> clazz = Class.forName("byv.PluginA", true, ClassLoader);
BasicPlugin obj = (BasicPlugin) clazz.newInstance();
obj.test(2);
}
}
Test打包成Test.jar
public class Boot {
public static void main(String... args) {
URL url1 = new File("PluginA.jar").toURI().toURL();
URL url2 = new File("BasePluginA.jar").toURI().toURL();
URL url3 = new File("Test.jar").toURI().toURL();
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {url1, url2});
classLoader.loadClass("Test").getMethod("main",new Class[]{args.getClass()}).invoke(null,new Object[]{args});
}
}
public static void main(String... args) {
BasicPlugin obj = new PluginA();
obj.test(2);
}
}