Расширение веб-приложений Java с помощью плагинов
У меня есть это веб-приложение, которое превратилось в неуправляемый беспорядок.
Я хочу разделить его на общую часть "фреймворка" (которая по-прежнему включает в себя такие веб-элементы, как страницы и изображения) и несколько модулей, которые добавляют дополнительную функциональность и экраны. Я хочу, чтобы этот рефакторинг также был полезен в качестве системы плагинов для сторонних расширений.
Все модули должны быть отдельными единицами развертывания, в идеале - файл war или jar.
Я попытался просто создать несколько обычных военных файлов, но Tomcat хранит (в соответствии со спецификацией сервлета) эти военные файлы полностью отдельно друг от друга, чтобы, например, они не могли делиться своими классами.
Мне нужно, чтобы плагины могли видеть "основной" путь к классам.
Мне нужно, чтобы основное приложение имело некоторый контроль над плагинами, например возможность перечислять их и устанавливать их конфигурацию.
Я хотел бы сохранить полное разделение между самими плагинами (если они не определяют зависимости) и любыми другими не связанными веб-приложениями, которые могут работать на том же Tomcat.
Я бы хотел, чтобы они были укоренены под префиксом "основного" URL-адреса приложения, но это не обязательно.
Я хотел бы использовать Tomcat (большие архитектурные изменения должны координироваться со слишком большим количеством людей), а также услышать о чистом решении в мире EJB или OSGi, если таковые имеются.
8 ответов
Я возился с идеей использования OSGi для решения той же проблемы, которую вы описываете. В частности, я смотрю на использование Spring Dynamic Modules.
Взгляните на портлеты Java - http://developers.sun.com/portalserver/reference/techart/jsr168/ - в двух словах, спецификацию, которая позволяет взаимодействовать между тем, что в противном случае является автономными веб-приложениями j2ee
Редактирование Я забыл упомянуть, что портлеты в значительной степени независимы от фреймворка - поэтому вы можете использовать Spring для родительского приложения, а отдельные разработчики могут использовать все, что захотят, в своих портлетах.
"Кроме того, я не уверен, что вы можете выполнить" пересылку "на другую WAR на сервере. Проблема в том, что пересылки используют относительный URL-адрес к корню веб-приложения, и у каждого WebApp есть свой собственный корень, поэтому вы просто "не можете добраться отсюда". Вы можете перенаправить, но это не то же самое, что форвард ".
Вы можете переслать в другую WAR, если эта WAR позволяет кому-то сделать это.
Glassfish и несколько WARS EAR: это имеет смысл.
Если вы поместите MAIN классы в общий CLASSPATH tomcat, то вы можете поместить свои отдельные PLUGIN в отдельные WAR-файлы.
Основное приложение также может быть частью сервлета TOMCAT, который вы определили в server.xml. Это может быть MASTER SERVLET, а все другие WAR могут контролироваться этим главным сервлетом.
Имеет ли это смысл?
BR,
~ A
Ваша основная проблема - сосредоточиться вокруг физических, статических ресурсов системы, а все остальное - просто, эффективно, баночки.
WAR в Tomcat разделены отдельными загрузчиками классов, но также они разделены на уровне сеанса (каждый WAR является отдельным веб-приложением и имеет свое собственное состояние сеанса).
В Glassfish, если WAR-файлы были объединены в EAR, они бы совместно использовали загрузчики классов (GF использует пространство загрузчика плоских классов в EAR), но все равно имели бы отдельное состояние сеанса.
Кроме того, я не уверен, что вы можете сделать "пересылку" на другую WAR на сервере. Проблема заключается в том, что перенаправители используют относительный URL-адрес к корню веб-приложения, и у каждого веб-приложения есть свой собственный корень, поэтому вы просто "не можете добраться отсюда". Вы можете перенаправить, но это не то же самое, что форвард.
Таким образом, эти функции веб-приложения сговорились против того, чтобы вы пытались равномерно развернуть их в контейнере.
Скорее, я думаю, что горячий совет - создать утилиту "ассемблер", которая берет ваши отдельные модули и "объединяет" их в одно веб-приложение. Он может объединять их web.xml, их содержимое, нормализовать jar и классы и т. Д.
WAR - это особенность и ошибка в мире Java. Я люблю их, потому что они действительно делают развертывание скомпилированных приложений "перетаскиванием" с точки зрения их установки, и эта функция используется гораздо чаще, чем то, с чем вы сталкиваетесь. Но я чувствую твою боль. У нас есть общая "базовая" структура, которую мы разделяем между приложениями, и нам в основном приходится постоянно объединять ее, чтобы поддерживать ее. Мы написали это, но это все еще немного болезненно.
Рассматривали ли вы использование maven для разделения ваших проектов, а затем разрешаете ли они зависимости между WAR и JAR? В конечном итоге вы получите дублирование библиотек между WAR, но только там, где это необходимо (и это не должно быть проблемой, если вы не попадаете в какое-то забавное занятие загрузчика классов).
Tomcat также позволяет вам настраивать кросс-контекстные приложения, если вам нужно перейти от одной WAR к другой относительно прозрачным способом...
Если вы хотите сохранить вещи в одном и том же веб-приложении (скажем, ROOT), вы могли бы создать прокси-веб-приложение, которое перенаправляет на другое соответствующее веб-приложение за кулисами, чтобы сделать его относительно прозрачным?
На самом деле нет ничего лучше, чем OSGI, если вы думаете о разделении приложения на отдельные модули. Взгляните на пример с Greenpages. Вы можете создать родительский модуль (ядро), куда вы включите jar-файлы, которые нужны вашему приложению.
Если вы что-то знаете о компонентном программировании, вы скоро обнаружите, что модули OSGI ведут себя как интерфейсы, где вы должны показать, что вы будете использовать в других модулях. Это довольно просто, когда вы понимаете. В любом случае, это также может быть очень больно, когда вы узнаете, как использовать OSGI. У нас были проблемы с использованием JSON, так как версия Джексона, которую мы добавили в модуль как jar, была переопределена другим jar, который содержался в основных модулях Spring. Вы всегда должны дважды проверить, какая версия jar загружена для ваших нужд.
К сожалению, даже подход OSGI не решает то, что мы ищем. Как расширить постоянную модель и существующие формы во время выполнения.
В зависимости от сложности функциональности плагина я бы также рассмотрел веб-сервис, например, реализованный с помощью Axis.
Ваше основное приложение затем настраивается с помощью URL-адреса веб-приложения (плагина), предоставляющего сервис.
Преимущество, на мой взгляд, двоякое:
- Вы получаете хороший, чистый, отлаживаемый API между двумя войнами, а именно сообщения Soap/XML
- Вы можете обновить один плагин без необходимости регрессионного тестирования всего приложения.
Недостатки в том, что вам нужно настроить некоторые проекты Axis, и что у вас должна быть какая-то конфигурация плагина. Кроме того, вам может потребоваться ограничить доступ к веб-приложениям ваших служб, поэтому может потребоваться некоторая настройка.
Если плагины работают с одной и той же базой данных, обязательно ограничьте время кэширования или настройте слой кэширования, охватывающий войну.
Я также пытался разработать общую или абстрактную среду, где я могу добавлять плагины (или модули) во время выполнения и улучшать существующее работающее веб-приложение.
Теперь, как вы сказали, предпочтительный способ сделать это с помощью файла WAR или JAR. Проблема с файлом WAR в том, что вы не можете развернуть его как плагин для существующего приложения. Tomcat развернет его как отдельный веб-контекст. Не желательно
Другой вариант - это файл JAR и написать собственный код, чтобы скопировать этот файл JAR в папку WEB-INF/lib и загрузить классы в существующий загрузчик классов. Проблема заключается в том, как развернуть не-Java-файлы, такие как JSP или файлы конфигурации. Для этого существует два решения: Используйте шаблоны скорости вместо JSP (b.), Чтобы написать собственный код для чтения JSP из пути к классам вместо контекстного пути.
Модули OSGI или Spring Dynamic хороши, но в настоящее время они выглядят слишком сложными для меня. Я еще раз посмотрю на это, если почувствую это.
Я ищу простой API, который может позаботиться о жизненном цикле плагина и все еще в состоянии использовать JSP в моем упакованном файле JAR.
Может быть, вы можете использовать un jar плагин во время развертывания и копировать файлы в правильные каталоги.