Горячая перезагрузка классов в отдельном потоке сервера - PullRequest
0 голосов
/ 12 февраля 2019

Я исследую способы реализации некоторой горячей перезагрузки классов 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 Ответ

0 голосов
/ 12 февраля 2019

Ключевой концепцией является не перезагрузка классов в Classloader, а создание отдельного экземпляра ClassLoader, который будет «удален» в случае, если вы выполняете перезагрузку кода.Общие библиотеки, которые не изменяются, могут быть размещены в вашем главном проекте, чтобы они были доступны через SystemClassLoader.

Создайте свой собственный «MyClassloader» и загрузите в него все свои файлы JAR и их зависимости.Используйте MyClassLoader для загрузки и выполнения основного класса загруженного кода.

Если вы хотите перезагрузить код, остановите все потоки, запущенные повторно загружаемым кодом.Обычно это должно поддерживаться самим потоком, например, путем регулярной проверки глобального статического поля MyClassLoader AtomicBoolean shutdown и прерывания потока в случае, если он чего-то ждет.

Как только все потоки закончили, единственная ссылка наКод - это ваш экземпляр MyClassLoader.Если вы отбросите этот экземпляр, весь код также будет удален, и вы можете начать все сначала.

...