java热重载类在服务器的单独线程中
我正在研究实现Java类的一些热重载的方法。我想到的技术是这样的:
- 将外部/核心库中的所有类保留在内存中
- 如果我的某个文件发生更改,请从内存中删除所有my类并重新加载所有类。我不必在内存中重新加载任何库,因为它们不会改变,也不依赖于我的文件/类李>
public class Server implements Runnable {
private Thread current;
public void run(){
// create a new classloader and load all my classes from disk?
}
public Server start(){
if(this.current != null){
this.current.destroy(); // not sure if this works
}
this.current = new Thread(r);
this.current.start();
return this;
}
public static void main(String[] args){
var s = new Server().start();
onFileChanges(filePath -> {
// we don't really care what file changed
// as long as it's one of our project's files, we reload all classes
s.start();
});
}
}
我认为关键的想法是我可以从我的项目中重新加载所有的类,而不是试图计算一些依赖树
我的主要问题是:
(a)如何停止/终止线程?线程销毁已弃用
(b)如何从内存中的类加载器中删除所有类
(c)如何在内存中保留库的所有类,但从内存中删除对代码的类/实例的所有引用
有人认为这项技术有效吗?是否可以实施
# 1 楼答案
关键的概念不是在类加载器中重新加载类,而是创建一个单独的类加载器实例,在执行代码重新加载时,该实例将被“删除”。可以将不变的共享库放置在主项目中,以便通过SystemClassLoader获得它们
创建自定义的“MyClassloader”,并将所有JAR文件及其依赖项加载到其中。 使用MyClassLoader加载并执行加载代码的主类
如果要重新加载代码,请停止由可重新加载代码启动的所有线程。这通常必须由线程本身来支持,例如,定期检查MyClassLoader全局静态字段
AtomicBoolean shutdown
,并在线程等待某个内容时中断线程所有线程结束后,对代码的唯一引用就是MyClassLoader实例。如果你扔掉这个实例,所有的代码也会被删除,你可以重新开始