java - 从动态加载的 jar 文件中加载具有父类(super class)的 Java 类

标签 java jar jvm classloader dynamic-class-loaders

我正在尝试从动态加载的 jar 文件加载类。目前,我可以加载不扩展为根类 Object 之外的类的类,但无法加载扩展自定义类的类。我的问题的详细描述如下。

在项目A中,有一个A类,如下所示:

class A {
}

在项目 B 中,有一个类 B1 和一个类 B2,如下所示:

class B1 {
}

class B2 extends A {
}

我将项目A导出到a.jar,将项目B导出到b.jar。测试代码为:

File f = new File("Z:\\Jars\\b.jar");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { f.toURL() },
        System.class.getClassLoader());

Class<?> classB1 = (Class<?>) urlClassLoader.loadClass("b.B1");
System.out.println("B1 is loaded");

Class<?> classB2 = (Class<?>) urlClassLoader.loadClass("b.B2");
System.out.println("B2 is loaded");

类B1加载成功,但由于类a.A未找到异常,类B2未加载:

java -cp a.jar;b.jar; a.Main
B1 is loaded
Exception in thread "main" java.lang.NoClassDefFoundError: a/A
Caused by: java.lang.ClassNotFoundException: a.A
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 12 more

如何解决这个问题? 谢谢。

PS。包含 a.jar 后,可以加载类 B2,但无法通过以下测试:

Class<A> classB2 = (Class<A>) urlClassLoader.loadClass("b.B2");
A ab2 = classB2.newInstance();

第一行正常,但第二行触发了以下异常:

Exception in thread "main" java.lang.ClassCastException: b.B2 cannot be cast to a.A
    at a.Main.main(Main.java:22)

B2 应该是 A 实例,知道为什么会发生这种情况吗?

最佳答案

您有两个名为 a.A 的类,一个由线程的默认类加载器加载,另一个由您的自定义类加载器加载。

这就是消息令人困惑的地方,因为您实际上有两个打印 a.A 的类,但是来自不同的类加载器,您无法将其中一个替换为另一个。你需要做的是

Class classB2 = urlClassLoader.loadClass("b.B2")
Object ab2 = classB2.newInstance();

这是因为您的线程将加载的 a.A 来自默认类加载器,即使它碰巧具有相同的名称,您也无法使用它。

解决此问题的另一种方法是仅让一个类加载器加载 a.A

File f = new File("Z:\\Jars\\b.jar");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { f.toURL() });

这将使用 ClassLoader.getSystemClassLoader() 加载 a.A,因此只有一个具有该名称的类。

关于java - 从动态加载的 jar 文件中加载具有父类(super class)的 Java 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40068413/

相关文章:

java - "Tag start is not closed"在 XML 元素的开始和结束标记内注释时

java - 尝试重复直到条件为假

java - META-INF/MANIFEST.MF 文件中的库依赖项

java - 有效的最终/最终限制不是没用吗?

javascript - JS实现文件上传进度

C++ 到 CLR 的字节码编译器?

java - 在 JComboBox.addItem(o) 中禁用 HTML 解析

java - 单例模式: getInstance() vs Passing the singleton object?

java - 如何在pom中引用第三方jar来创建 super jar

java - [Java]通过控制台使用 jar 文件输出不正确