有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java热重载类在服务器的单独线程中

我正在研究实现Java类的一些热重载的方法。我想到的技术是这样的:

  1. 将外部/核心库中的所有类保留在内存中
  2. 如果我的某个文件发生更改,请从内存中删除所有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) 个答案

  1. # 1 楼答案

    关键的概念不是在类加载器中重新加载类,而是创建一个单独的类加载器实例,在执行代码重新加载时,该实例将被“删除”。可以将不变的共享库放置在主项目中,以便通过SystemClassLoader获得它们

    创建自定义的“MyClassloader”,并将所有JAR文件及其依赖项加载到其中。 使用MyClassLoader加载并执行加载代码的主类

    如果要重新加载代码,请停止由可重新加载代码启动的所有线程。这通常必须由线程本身来支持,例如,定期检查MyClassLoader全局静态字段AtomicBoolean shutdown,并在线程等待某个内容时中断线程

    所有线程结束后,对代码的唯一引用就是MyClassLoader实例。如果你扔掉这个实例,所有的代码也会被删除,你可以重新开始