gpt4 book ai didi

java - 如何动态加载具有公共(public)抽象类的 jar?

转载 作者:行者123 更新时间:2023-11-30 09:36:33 25 4
gpt4 key购买 nike

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

//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;
}
}

上面的子类被编译并打包成一个jar文件(PluginA.jar)。这个 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)

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

最佳答案

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

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

关于java - 如何动态加载具有公共(public)抽象类的 jar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10698049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com