我正在编写一个需要在运行时重新加载以前加载的类的应用程序。原因是该类在运行时自动生成,新实现改变了应用程序的工作方式。我只生成所述类的一个对象,并且我从所有依赖项中删除它,但是一个定义常量值的接口。重新加载时重置任何或所有成员的值都没有问题。我知道它何时发生变化,我可以控制它。我唯一的问题是重装本身。
根据我的阅读,我应该使用ClassLoader。我试图这样做,但我不能让它发挥作用。
我尝试了以下内容:
myClassObject.getClass().getClassLoader()
)并使用它来重新加载类 - 不起作用。它可能会继续加载旧的实现。getClassLoader()
,但我发现它们不匹配。-Djava.system.class.loader=com.test.Reoader com.test.myMainClass
以使其成为默认的重新加载器,但我从编译器中收到错误。我知道我应该覆盖默认的ClassLoader,但我所做的一切似乎都没有成功。
我的ClassLoader:
public class Reloader extends ClassLoader {
public Reloader(){
super(Reloader.class.getClassLoader());
}
@Override
public Class<?> loadClass(String s) {
return findClass(s);
}
@Override
public Class<?> findClass(String s) {
try {
byte[] bytes = loadClassData(s);
return defineClass(s, bytes, 0, bytes.length);
} catch (IOException ioe) {
try {
return super.loadClass(s);
} catch (ClassNotFoundException ignore) {}
ioe.printStackTrace(java.lang.System.out);
return null;
}
}
private byte[] loadClassData(String className) throws IOException {
File f = new File("out\\production\\ManoCPU\\" + className.replaceAll("\\.", "/") + ".class");
int size = (int) f.length();
byte buff[] = new byte[size];
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
dis.readFully(buff);
dis.close();
return buff;
}
}
非常感谢任何可以提供帮助的人。
答案 0 :(得分:1)
您只能加载一次类(每个类加载器的实例)。这意味着您必须丢弃已加载类的类加载器,并为更新版本的类实例化一个新的加载器。
当处理多个类加载器时,还要记住,如果使用多个类加载器加载相同的类,则它们不会被识别为同一个类。