Динамически загружаемые и выгружаемые модули приложений в Java - как?

Я пишу серверное приложение, которое использует внешние модули. Я хотел бы сделать их обновляемыми без перезагрузки сервера. Как я могу это сделать? Я нашел OSGi, но он выглядит очень сложным и большим для моей задачи.

Простые *.jar файлы в порядке, но, как только они загружены, я полагаю, я не могу выгрузить их из ВМ и заменить на другую версию на лету.

Какой подход вы можете предложить?

5 ответов

Решение

Кажется, что OSGi - это именно то, что вы просите. Это может быть сложно, но есть способы справиться с этим. Некоторая сложность может быть уменьшена с помощью SpringDM или чего-то подобного для решения стандартных задач регистрации и использования сервисов во время выполнения. Регистрация служб, управляемая аннотациями, и внедрение зависимостей действительно сокращают объем кода, который необходимо написать.

Другой способ уменьшить сложность - развернуть основную часть вашего приложения в одном пакете и развертывать только те части, которые должны быть модульными, в свои собственные пакеты. Это снижает вероятность регистрации и использования служб из других пакетов во время выполнения, а также снижает сложность развертывания. Код, работающий в пакете, может использовать другой код в том же пакете, как и в стандартном приложении Java - нет необходимости взаимодействовать со средой выполнения OSGi. Противоположностью этого подхода является разбиение вашего приложения на множество отдельных пакетов, которые экспортируют четко определенные сервисы в другие пакеты в системе. Хотя это очень модульный подход, он сопряжен с дополнительной сложностью управления всеми этими пакетами и большим взаимодействием со средой исполнения OSGi.

Я бы посоветовал взглянуть на книгу "OSGi в действии", чтобы получить представление о проблемах и ознакомиться с приличными образцами.

По крайней мере, это потребует от вас определения вашего пользовательского загрузчика классов... Я не понимаю, как это может быть проще, чем просто использовать Felix, Equinox, Knoplerfish или любую среду исполнения Osgi с открытым исходным кодом для выполнения этой задачи. Может быть, SpringDM проще...

Если вы будете следовать ClassLoader маршрут (это не так сложно, на самом деле), я предлагаю, чтобы каждый модуль был упакован в свой собственный jar-файл и использую другой ClassLoader для чтения каждого jar-файла. таким образом, выгрузка модуля - это то же самое, что "сброс" ClassLoader.

То, ради чего ты идешь, определенно возможно. Я считаю, что вы можете выгрузить классы из памяти, загрузив их в отдельный ClassLoader, а затем избавившись от этого ClassLoader. Если вы не хотите полностью использовать OSGI, я бы порекомендовал что-то вроде JBoss Microcontainer (http://www.jboss.org/jbossmc) или ClassWorlds (http://classworlds.codehaus.org/). Не так уж сложно написать что-то подобное с нуля, если ваши потребности достаточно специализированы.

Надеюсь, это поможет, Нейт

OSGi не так сложна - использование PAX Runner с Maven работало на одном дыхании.

Или реализуйте свой собственный ClassLoader и установите его в JVM: java -Djava.system.class.loader=com.test.YourClassLoader App.class

Другие вопросы по тегам