在我的代码中,我想从Jar文件中动态加载Module类实现。
在我的目录中,我有3个文件:A.jar,B.jar,C.jar 每个jar都有一个名为Main的类,它扩展了Module类
A.jar代码示例:
public class Main extends Module {
private static String name = "A";
public Main() {
super(name);
}
}
(B和C文件相同,但在名称属性中使用“B”和“C”代替“A”。)
我的模块类代码是:
public abstract class Module{
private StringProperty nameProperty;
public Module(String name){
this.nameProperty = new SimpleStringProperty(name);
}
public StringProperty nameProperty(){
return nameProperty;
}
}
这是我用来动态加载这三个类的代码:
for (File moduleFile : Data.modulesDir.listFiles()) {
try {
URL url = moduleFile.toURI().toURL();
Class[] parameters = new Class[] { URL.class };
URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> sysClass = URLClassLoader.class;
Method method = sysClass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysLoader, new Object[] { url });
Constructor<?> cs = ClassLoader.getSystemClassLoader().loadClass("com.ehzlab.webreaper.module.Main")
.getConstructor();
Module instance = (Module) cs.newInstance();
System.out.println(instance.nameProperty.get());
} catch (Exception e) {
e.printStackTrace();
}
}
我期待这个输出:
A
B
C
但我得到了这个:
A
A
A
似乎在每个文件列表迭代中加载相同的jar。但调试我注意到URL每次都在变化。 我也尝试颠倒顺序,例如,将B.jar放在另一个jar之前,输出为:
B
B
B
为什么?
答案 0 :(得分:0)
只是因为您每次都使用相同的类加载器,而不会重新加载基础类:
ClassLoader.getSystemClassLoader()...
为了访问特定的类,您必须使用适当的类加载器来加载特定的jar
文件(可能是sysLoader
,不确定,因为我没有检查):
Constructor<?> cs = sysLoader.loadClass("com.ehzlab.webreaper.module.Main")
.getConstructor();