Меня попросили создать систему Java, которая будет иметь возможность загружать новый код (расширения) во время выполнения. Как мне повторно загрузить файл jar во время выполнения моего кода? или как мне загрузить новый jar?
Очевидно, поскольку важно постоянное время безотказной работы, я хотел бы добавить возможность перезагрузки существующих классов во время выполнения (если это не слишком усложнит задачу).
На что мне следует обратить внимание? (думайте об этом как о двух разных вопросах - один касается перезагрузки классов во время выполнения, другой касается добавления новых классов).
Переведено автоматически
Ответ 1
Перезагрузка существующих классов с существующими данными, скорее всего, приведет к сбоям.
Вы можете относительно легко загружать новый код в новые загрузчики классов:
Больше не используемые загрузчики классов можно использовать для сбора мусора (если только нет утечки памяти, как это часто бывает при использовании ThreadLocal, драйверов JDBC, java.beans и т.д.).
Если вы хотите сохранить данные объекта, то я предлагаю механизм сохранения, такой как сериализация, или что-то еще, к чему вы привыкли.
Конечно, системы отладки могут делать более причудливые вещи, но они более хакерские и менее надежные.
В загрузчик классов можно добавлять новые классы. Например, с помощью URLClassLoader.addURL. Однако, если класс не загружается (скажем, потому, что вы его не добавили), то он никогда не загрузится в этом экземпляре загрузчика класса.
Меня попросили создать систему java, которая будет иметь возможность загружать новый код во время выполнения
Возможно, вы захотите основать свою систему на OSGi (или, по крайней мере, приложить к этому много усилий), которая была создана именно для этой ситуации.
Возня с загрузчиками классов - действительно сложное дело, в основном из-за того, как работает видимость классов, и вы не хотите позже столкнуться с проблемами, которые трудно отладить. Например, Class.forName(), который широко используется во многих библиотеках, не слишком хорошо работает во фрагментированном пространстве classloader.