首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用公共抽象类动态加载jar?

如何使用公共抽象类动态加载jar?
EN

Stack Overflow用户
提问于 2012-05-22 16:00:56
回答 2查看 4.5K关注 0票数 2

我正在尝试开发一个插件系统,它提供了一个在运行时加载jar的接口。每个jar包含一个从公共抽象类扩展而来的类。例如:

代码语言:javascript
复制
//BasicPlugin.java
package byv;

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

我实现了一个子类:

代码语言:javascript
复制
//PluginA.java
package byv;

import byv.BasicPlugin;

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

上面的子类被编译并打包到一个jar文件(PluginA.jar)中。这个jar只包含PluginA.class。然后在主项目中,我使用URLClassLoader加载它:

代码语言:javascript
复制
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的引用。但是错误仍然发生:

代码语言:javascript
复制
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)

那么我该如何解决这个问题呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-22 16:09:40

因为它是一个IllegalAccessError,所以我建议你公开BasicPlugin来解决这个问题。据我所知,你定义的类是包保护的。因此,不能从不同的类加载器访问它。因为这就是你的插件所需要的,所以除了public之外,将类设置为public是没有意义的。

还有一件事,URLClassLoader有第二个构造器,你可以在其中指定父加载器。然后,这个加载器被用来加载插件类。在更复杂的环境中,您可能需要指定加载器。目前您的代码或多或少地使用了系统加载器,这在您的示例中是可以的,但我不知道您稍后打算做什么。BasicPlugin.class.getClassLoader()肯定会为该类提供正确的加载器。

票数 1
EN

Stack Overflow用户

发布于 2012-05-22 16:10:49

传递构造URLClassLoader实例时要使用的类加载器上下文:

代码语言:javascript
复制
URLClassLoader ClassLoader = URLClassLoader.newInstance(new URL[] {url},
                                                        this.getClassLoader());
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10698049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档