Как создать "модульную" Java-программу, которая обновляется во время работы?
Я поиграл с идеей создания программы, которая может выполнять несколько различных задач, находясь под контролем центрального потока. Идея состоит в том, чтобы создать базовую программу, которая будет искать и загружать отдельные модули, когда она запускается / работает. Эти модули будут выполнять свои собственные задачи перед передачей готовых объектов в другой модуль, который будет обрабатывать что-то, например, загружать готовый продукт на веб-сервер или организовывать полученные данные в заранее определенную структуру файлов / папок (см. Изображение для основной концепции). Я никогда прежде не работал с модульным дизайном в Java; все мои прошлые программы были полностью самодостаточными, поэтому я почти не представляю, с чего начать.
Моя цель состоит в том, чтобы хранить внешние библиотеки в основной программе (например, AWS SDK для Java, которая может снимать файл.jar размером до 18 МБ), чтобы отдельные модули можно было распределять практически мгновенно при выполнении обновления, а не необходимость перераспределения всей, 18MB+ автономной программы только для того, чтобы исправить ошибку в 1 строку. Кроме того, я хотел бы иметь возможность обновлять отдельные модули, когда это необходимо, без необходимости перезапуска всей программы, позволяя другим модулям продолжать работу, пока один обновляется, сокращая общее время простоя, так что программа требует только времени полностью выключается, когда производится обновление ядра.
Я хочу знать, возможно ли это (я так полагаю) , и если это так; что я должен посмотреть / как бы я настроить? (Пытаюсь ли я заново изобрести колесо? Если да, где я могу найти это колесо?)
Я посмотрел на использование ServiceLoader
и поиграл с примером здесь, но я не уверен, как я мог бы указывать один модуль на другой с его помощью или если он может извлекать библиотечные классы из ядра, или если он может выполнять упомянутое "активное обновление". До сих пор я видел только то, что (в моем примере) ядро может обращаться к модулю, но я не уверен, может ли модуль получить доступ к ядру.
Не уверен, имеет ли это отношение к посту, но я делаю всю свою работу в Eclipse (подумал, стоит упомянуть, если есть инструмент, специфичный для IDE).
2 ответа
Взгляните на OSGi, Bundle Structure - это в основном то, что вы ищете. С OSGi вы создаете "пакеты", которые являются jar-файлами с метаданными, чтобы сообщить среде выполнения (например, Apache Felix или Eclipse Equinox), какие зависимости у вашего пакета есть и что он предлагает. С OSGi вы можете запускать, останавливать и обновлять каждый комплект независимо от всех остальных, и он даже перестает зависеть от других функций и перезапускает их после обновления комплекта (при условии, что вы правильно настроили его;))
@bhspencer: просто загрузка новых jar-файлов не позволяет корректно обновляться, потому что стандартный загрузчик классов java не позволяет выгружать классы.
Вы не можете разгрузить Class
из ClassLoader
, но вы можете разгрузить весь ClassLoader
из JVM путем обнуления всех ссылок на него и на все экземпляры классов, которые он загрузил. URLClassLoader
делает хорошую отправную точку.