我正在尝试开发一个插件系统,它提供了一个在运行时加载jar的接口。每个jar包含一个从公共抽象类扩展的类。例如:
//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)。这个罐子只包含插件A.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)
那么我该如何解决这个问题呢?
传递构造 URLClassLoader
实例时要使用的类加载器上下文:
URLClassLoader ClassLoader = URLClassLoader.newInstance(new URL[] {url},
this.getClassLoader());
由于它是一个非法访问错误
,我建议你公开BasicPlugin
来解决问题。据我所知,您定义的类是包保护的。因此,无法从不同的类装入器访问它。由于这是您的插件所需要的,因此使类公开之外没有任何意义。
还有一件事,URLClassLoader
有第二个构造函数,您可以在其中指定父加载器。然后使用此加载器加载插件类。在更复杂的环境中,您可能需要指定该加载器。目前,您的代码或多或少使用了系统加载器,这在您的示例中是可以的,但我不知道您稍后打算做什么。BasicPlugin.class.getClassLoader()
无疑为该类提供了正确的加载器。
嗨,我有一个抽象类,其中有一些公共方法和一些抽象方法。我让公众知道,他们实现了派生类的通用方法。 让我困惑的是,为什么我想定义一个公共抽象方法,而不是受保护的抽象方法。在抽象类中定义公共抽象方法对我来说毫无意义。。。。因为if是一个抽象,在派生类中会被重写,但if被定义为public也是一样的,但在某种程度上,将其定义为protected更有意义,因为我们知道,我们将在派生类中重写它。 在抽象类中
我有一个抽象类的许多子类,每个子类都声明了一个同名的公共静态final字段。我在考虑在抽象超类中包含这个字段,而不初始化它,并希望每个子类都能被强制初始化它。 我之所以这么想,是因为抽象类的所有子类都声明了一个名为UNIQUE_ID的公共静态最终字符串字段,并且每个子类都有必要声明一个具有该名称的字段。 我希望我的问题足够清楚,如果不清楚,请告诉我。 能不能做一些和这个差不多的事情? 编辑:添加代
如何调用从公共静态空白到非静态的公共空白碎片类?或者有另一种方法在(listViewHolder.dot.setOnClickListener(new View.OnClickListener()和公共无效搜索3())
我得到了一个抽象类: 和两个自动生成的子类: 以及一个用于创建网络模式(请求/回复)的应用编程接口,该模式使用请求类型和回复类型(A和B预计将像上述那样是自动生成的FOPACImpl子类): 我从XML存根中提取主题字符串,以及两种类型A和B的字符串名称: 显然,Java中的反射不能直接处理“公共抽象”超类? 结果 1) 为什么“使用“受保护”的修饰符”?FooPACImpl。getClass()
问题内容: 我查找了语法并搜索了api,但仍然对该过程感到困惑。我还搜索了Stackoverflow。加载类并从中动态创建对象的正确方法是什么?换句话说,我希望用户指定要创建的对象类型,然后创建该类型的对象。我不需要菜单,因为我希望他们能够选择当前目录中的任何类。 问题答案: 假设该类具有无参数构造函数,则最简单的方法是- 参考-java.lang.Class
在谷歌代码上提供的ehcache spring注解库中,一个配置选项“创建缺少的缓存”可用于动态创建缓存(缓存未在ehcache.xml中定义)。纯spring ehcache抽象(spring 3.1.1)中是否有类似的配置?或者有没有其他方法可以使用spring ehcache抽象创建动态缓存?
问题内容: 请查看下面的修改 我正在尝试创建一个 JShell实例 ,该 实例 使我可以访问它,并让我与创建它的 JVM中的 对象进行交互。这对于在编译时可用的类很好,但对于 动态 加载的类却失败了。 另外,与交换可以得到相同的结果,但是我不理解两个类之间的区别。 如何使 运行时 加载的类可用于此 JShell实例 ? 编辑:此问题的第一部分已解决,下面是更新的源代码,以演示问题的第二部分 如果
我最近遇到了以下方法。我试着用谷歌搜索,并通过定义如下方法,做了一个例子来了解差异;两者似乎是一样的。但是,我需要知道它是否真的是一样的? 注意:在以上两种方法中,公共代码和抽象代码已经互换。