Помимо EAR и EJB, что я получаю с сервера приложений Java EE, который я не получаю в контейнере сервлетов, таком как Tomcat?
Мы используем Tomcat для размещения наших приложений на основе WAR. Мы являемся совместимыми с сервлет-контейнерами приложениями J2EE, за исключением org.apache.catalina.authenticator.SingleSignOn.
Нам предлагается перейти на коммерческий сервер приложений Java EE.
- Первый недостаток в изменении этого
Я вижу, это стоимость. Не важно что
плата за заявку
сервер, Tomcat является бесплатным.
- Во-вторых, сложность. Мы не
используйте функции EJB или EAR (из
конечно нет, мы не можем), и не пропустили их.
В чем же преимущества, которые я не вижу?
Каковы недостатки, о которых я не упоминал?
Упомянутые были...
- JTA - API транзакций Java - Мы
контролировать транзакцию через базу данных
хранимые процедуры.
- JPA - API Java Persistence - мы используем
JDBC и снова хранимые процедуры для
сохраняются.
- JMS - Служба сообщений Java - мы используем
XML через HTTP для обмена сообщениями.
Это хорошо, пожалуйста, больше!
Ответы
Ответ 1
Если вам не нужен EJB, вам не нужен полный стек J2EE-сервера (коммерческий или нет).
У вас может быть большинство функций J2EE (таких как JTA, JPA, JMS, JSF) без полного J2EE-сервера стека. Единственное преимущество полного j2ee для стека состоит в том, что контейнер будет обрабатывать все это от вашего имени декларативно. С появлением EJB3, если вам нужны управляемые контейнером службы, использование одного - это хорошо.
У вас также может отсутствовать полный полный сервер стека, такой как Glasfish, Geronimo или JBoss.
Вы также можете запускать внедренные j2ee-контейнеризованные службы со встроенным Glasfish, например, внутри Tomcat.
Вам может понадобиться контейнер EJB, если вы хотите хорошо использовать сеанс beans, сообщение beans, таймер beans, даже с кластеризацией и сбой.
Я бы посоветовал руководству рассмотреть возможность обновления на основе потребности в функциях. Некоторые из этих EJB-контейнеров могут просто использовать встроенный Tomcat в качестве своего веб-сервера, поэтому что дает!
Некоторые менеджеры просто любят платить за вещи. Попросите их подумать о пожертвовании в городском приюте или просто пойти на BEA.
Ответ 2
Когда мы отправимся с целью Java EE 6 сертифицировать Apache Tomcat как Apache TomEE, вот некоторые из недостатков, которые мы должны были заполнить, чтобы, наконец, пройти Java EE 6 TCK.
Не полный список, но некоторые основные моменты, которые могут быть не очевидны даже при существующих ответах.
Нет TransactionManager
Управление транзакциями обязательно требуется для любого сертифицированного сервера. В любом веб-компоненте (сервлет, фильтр, прослушиватель, jsf managed bean) вы должны получить UserTransaction
, как показано ниже:
-
@Resource UserTransaction transaction;
Вы можете использовать javax.transaction.UserTransaction
для создания транзакций. Все ресурсы, которые вы касаетесь в рамках этой транзакции, должны быть включены в эту транзакцию. Сюда входят, но не ограничиваются следующими объектами:
-
javax.sql.DataSource
-
javax.persistence.EntityManager
-
javax.jms.ConnectionFactory
-
javax.jms.QueueConnectionFactory
-
javax.jms.TopicConnectionFactory
-
javax.ejb.TimerService
Например, если в сервлете вы начинаете транзакцию, то:
- Обновление базы данных
- Оставьте сообщение JMS в теме или очереди
- Создайте таймер для работы в какой-то более поздней точке.
.. и затем одна из этих вещей терпит неудачу, или вы просто вызываете rollback()
на UserTransaction
, тогда все эти вещи отменены.
Нет пула соединений
Чтобы быть предельно ясным, существуют два типа пула соединений:
- Транзакционный пул соединений
- Неконтактный пул соединений
Спецификации Java EE строго не требуют пула соединений, однако, если у вас есть пул соединений, это должно быть транзакцией или вы потеряете управление транзакциями.
Это означает в основном:
- Каждый из тех же транзакций должен иметь такое же соединение из пула
- Соединение не должно возвращаться в пул до завершения транзакции (фиксация или откат), независимо от того, кто-то вызвал
close()
или любой другой метод на DataSource
.
Общей библиотекой, используемой в Tomcat для объединения пулов, является commons-dbcp. Мы также хотели использовать это в TomEE, однако он не поддерживал пул соединений с транзакциями, поэтому мы фактически добавили эту функциональность в commons-dbcp (yay, Apache), и она есть в версии commons-dbc версии 1.4.
Обратите внимание, что добавления Commons-dbcp в Tomcat все еще недостаточно для объединения пулов транзакций. Вам по-прежнему нужен диспетчер транзакций, и вам все еще нужен контейнер для сантехники регистрации соединений с объектами TransactionManager
через Synchronization
.
В Java EE 7 говорится о добавлении стандартного способа шифрования паролей БД и их пакетах с приложением в защищенном файле или внешнем хранилище. Это будет еще одна функция, которую Tomcat не поддерживает.
Без интеграции безопасности
Безопасность WebServices, безопасность JAX-RS, безопасность EJB, вход в JAAS и JAAC - все концепции безопасности, которые по умолчанию не подключены к Tomcat, даже если вы отдельно добавляете библиотеки, такие как CXF, OpenEJB и т.д.
Эти API-интерфейсы, конечно же, предполагают совместную работу на сервере Java EE. Нам потребовалась небольшая работа, чтобы заставить все это сотрудничать и сделать это поверх API Tomcat Realm
, чтобы люди могли использовать все существующие реализации Tomcat Realm
для управления своей "Java EE", безопасность. Это действительно по-прежнему безопасность Tomcat, она очень хорошо интегрирована.
Интеграция JPA
Да, вы можете отправить JPA-провайдера в файл .war и использовать его без помощи Tomcat. При таком подходе вы не получите:
-
@PersistenceUnit EntityManagerFactory
инъекция/поиск
-
@PersistenceContext EntityManager
инъекция/поиск
-
EntityManager
подключен к пулу соединений, поддерживающему транзакцию.
- Поддержка JTA
EntityManager
- Расширенные контексты сохранения
JTA-Managed EntityManager
в основном означает, что два объекта в одной транзакции, которые хотят использовать EntityManager
, будут видеть один и тот же EntityManager
, и нет необходимости явно передавать EntityManager
вокруг. Все это "прохождение" выполняется для вас контейнером.
Как это достигается? Простой, EntityManager
, который вы получили из контейнера, является подделкой. Это обертка. Когда вы используете его, он просматривает текущую транзакцию для реального EntityManager
и делегирует вызов этому EntityManager
. В этом причина таинственного метода EntityManager.getDelegate()
, поэтому пользователи могут получить реальныйEntityManager, если они хотят и используют любые нестандартные API. Делайте это с большой осторожностью и никогда не держите ссылку на делегата EntityManager
или у вас будет серьезная утечка памяти. Делегат EntityManager
обычно будет очищаться, закрываться, очищаться и отбрасываться, когда транзакция завершается. Если вы все еще держите ссылку, вы предотвратите сбор мусора этого EntityManager
и, возможно, все данные, которые он держит.
- Всегда безопасно хранить ссылку на
EntityManager
, которую вы получили из контейнера
- Неверно держать ссылку на
EntityManager.getDelegate()
- Будьте очень осторожны с ссылкой на
EntityManager
, которую вы создали через EntityManagerFactory
, на 100% отвечаете за его управление.
Интеграция CDI
Я не хочу упрощать CDI, но я считаю, что он слишком большой, и многие люди не очень серьезно смотрят - это в список "когда-нибудь" для многих людей:) Итак, вот просто я думаю, что "веб-парень" хотел бы узнать о нем.
Вы знаете все, что вы делаете и делаете в типичном webapp? Собирать вещи в и из HttpSession
весь день? Используя String
для ключевых и непрерывных объектов, которые вы получаете из HttpSession
. Вероятно, вы используете код утилиты для этого.
У CDI тоже есть этот код утилиты, он называется @SessionScoped
. Любой объект, аннотированный с помощью @SessionScoped
, получает и отслеживает в HttpSession
для вас. Вы просто запрашиваете, чтобы объект был введен в ваш сервлет через @Inject FooObject
, и контейнер CDI будет отслеживать "реальный" экземпляр FooObject таким же образом, как я описал транзакционное отслеживание EntitityManager
. Abracadabra, теперь вы можете удалить кучу кода:)
Выполнение каких-либо getAttribute
и setAttribute
на HttpServletRequest
? Ну, вы также можете удалить это с помощью @RequestScoped
.
И, конечно, существует @ApplicationScoped
для устранения вызовов getAttribute
и setAttribute
, которые вы могли бы выполнять на ServletContext
Чтобы сделать вещи еще более холодными, любой объект, отслеживаемый таким образом, может реализовать @PostConstruct
, который вызывается при создании bean и методе @PreDestroy
, который должен быть уведомлен, когда указанная область видимости завершена (сеанс завершено, запрос завершен, приложение закрывается).
CDI может сделать намного больше, но этого достаточно, чтобы кто-то захотел перезаписать старый webapp.
Некоторые придирчивые вещи
В Java EE 6 есть некоторые вещи, которые в рулевой рубке Tomcats не добавлены. Они не требуют больших объяснений, но объясняют большой кусок "заполнения пробелов".
- Поддержка
@DataSourceDefinition
- Поддержка глобального JNDI (
java:global
, java:app
, java:module
)
- Enum injection через
@Resource MyEnum myEnum
и
- Ввод класса через
@Resource Class myPluggableClass
и
- Поддержка
@Resource(lookup="foo")
Незначительные точки, но может быть невероятно полезно определить DataSource
в приложении переносимым способом, делиться записями JNDI между webapps и иметь простую власть сказать "посмотреть эту штуку и ввести ее"
Заключение
Как уже упоминалось, не полный список. Не упоминается EJB, JMS, JAX-RS, JAX-WS, JSF, bean Валидация и другие полезные вещи. Но, по крайней мере, некоторые идеи о вещах часто упускают из виду, когда люди говорят о том, что такое Tomcat, и нет.
Также имейте в виду, что то, что вы могли бы подумать как "Java EE", может не соответствовать фактическому определению. С веб-профилем Java EE сократилась. Это было намеренно, чтобы обратиться к "Java EE слишком тяжело, и мне не нужно все это".
Если вы вырезали EJB из веб-профиля, вот что вы оставили:
- Сервлеты Java
- Серверные страницы Java (JSP)
- Java ServerFaces (JSF)
- API транзакций Java (JTA)
- Java Persistence API (JPA)
- Контексты Java и инжекция зависимостей (CDI)
- Bean Проверка
Это довольно полезный стек.
Ответ 3
Если вас попросят перейти на коммерческий J2EE-сервер, причины могут не иметь ничего общего со стеком J2EE, но с нетехническими соображениями.
Одна вещь, которую вы получаете с коммерческим предложением J2EE, которое вы не получаете с Tomcat, - это техническая поддержка.
Возможно, это не относится к вам, в зависимости от уровней обслуживания, которые должны выполнять ваши веб-приложения. Могут ли ваши приложения отключиться, когда вы попытаетесь выяснить проблему с Tomcat, или это будет серьезной проблемой?
Ответ 4
Стоимость не обязательно является недостатком, так как есть несколько бесплатных серверов J2EE, например. JBoss и Glassfish.
В вашем вопросе предполагается, что (J2EE = Servlet + EJB + EAR), поэтому нет смысла использовать что-либо большее, чем контейнер Servlet, если вы не используете EJB или EAR. Это просто не так, J2EE включает намного больше, чем это. Примеры включают:
- JTA - API транзакций Java
- JPA - API сохранения Java
- JMS - спецификация Java-сообщений
- JSF - технология для создания пользовательских интерфейсов из компонентов
Cheers,
Донал
Ответ 5
По правде говоря, с огромным набором доступных пакетов и библиотек, мало контейнера EJB, который не может быть добавлен в современный контейнер сервлетов (ala Tomcat). Итак, если вы когда-либо хотели какие-либо из этих функций, вы можете получить их "ala carte", так сказать, с затратами, являющимися процессом интеграции этой функции в ваше приложение.
Если вы сейчас не "упускаете" какую-либо из этих функций, то с практической точки зрения вам, вероятно, не нужны.
Все сказанное говорит, что современные контейнеры EJB действительно приятны и поставляются со всеми этими услугами, предварительно интегрированными, что делает их несколько более удобными, если вы когда-либо захотите их. Иногда наличие функции рядом и удобно достаточно, чтобы заставить кого-то исследовать ее по своему потенциалу в их применении, а также увидеть интеграционный процесс функции как препятствие для принятия.
С качеством бесплатных контейнеров EJB очень сложно представить, как покупка может быть полезной, особенно если у вас нет реального спроса на нее в настоящий момент.
Тем не менее, я действительно рекомендую вам на самом деле получить его и поиграть с ним и изучить платформу. Glassfish очень легко начать и очень хорошо, и вы должны легко взять свою WARs как есть (или с очень небольшими изменениями).
Как правило, когда дело доходит до запуска Tomcat против контейнера EJB, вопрос действительно, почему НЕ использовать его? Говоря конкретно о Glassfish, я считаю, что это проще в использовании, чем Tomcat. Основное отличие заключается в том, что он может иметь умеренно больший объем памяти (особенно для небольшого приложения), чем Tomcat, но в большом приложении вы даже не заметите, что, Для меня поражение памяти не имеет большого значения, для других это может быть проблемой.
И он дает мне один источник всех этих приятных функций без необходимости сканировать сеть для стороннего варианта.