Проблема в том, что классы должны быть найдены в моей системе ClassLoader
, а не в новой ClassLoader
.
Похоже, что ваше текущее решение перезапустить JVM - единственный чистый способ сделать это.
Систему ClassLoader
нельзя изменить, и вы не можете добавить дополнительные JAR-файлы в это во время выполнения.
(Если вы пытались использовать отражение, чтобы связываться со структурами данных системного загрузчика классов, в лучшем случае это будет непереносимо и зависит от версии. В худшем случае это будет либо подвержено ошибкам ..., либо заблокировано JVM механизмы безопасности во время выполнения.)
Решение, предложенное в комментарии Йоханнесом Куном, не будет работать. Свойство java.system.class.loader
проверяется во время JVM bootstrap. К тому времени, когда ваше приложение работает, внесение изменений в него не будет иметь никакого эффекта. Я не убежден, что подход в его Ответе тоже сработает.
Вот один из возможных альтернативных способов справиться с этим ... если вы можете решить, какие недостающие JAR-файлы достаточно рано.
Напишите себе класс Launcher, который выполняет следующие действия:
- Сохраните аргументы командной строки
- Найдите файл JAR приложения
- Извлеките атрибуты Main-Class и Class-Path из MANIFEST.MF.
- Выясните, какой реальный путь к классу должен быть основан на вышеупомянутом ... и других спецификациях приложения c logi c.
- Создайте новый
URLClassLoader
с правильным путем к классу и системным загрузчиком классов в качестве его родителя. - Используйте его для загрузки основного класса.
- Используйте отражение, чтобы найти Основные классы
main
метод. - Вызывайте его, передавая аргументы командной строки сохранения.
По сути, это подход, который Spring Bootstrap и OneJar (и другие вещи) используют для обрабатывать про "баночки в банке" кровоизлияние и так далее. Это позволяет избежать запуска 2 виртуальных машин.