Помимо EAR и EJB, что я получу от сервера приложений Java EE, которого я не получаю в контейнере сервлета, таком как Tomcat? - PullRequest
23 голосов
/ 06 ноября 2008

Мы используем Tomcat для размещения наших WAR-приложений. Мы являемся J2EE-приложениями, совместимыми с сервлетами, за исключением org.apache.catalina.authenticator.SingleSignOn.

Нас просят перейти на коммерческий сервер приложений Java EE.

  1. Первый недостаток изменения этого Я вижу это стоимость. Не важно что сборы за применение сервер, Tomcat бесплатный.
  2. Второе - сложность. Мы не использовать функции EJB или EAR (из конечно нет, мы не можем) и не пропустили их.

Каких же преимуществ я не вижу?

Какие недостатки я не упомянул?


Упомянуто было ...

  1. JTA - API транзакций Java - Мы контролировать транзакцию через базу данных хранимые процедуры.
  2. JPA - Java Persistence API - Мы используем JDBC и снова хранимые процедуры для сохраняются.
  3. JMS - Служба сообщений Java - Мы используем XML поверх HTTP для обмена сообщениями.

Это хорошо, пожалуйста, больше!

Ответы [ 5 ]

58 голосов
/ 08 февраля 2012

Когда мы поставили перед собой цель, чтобы Java EE 6 сертифицировала Apache Tomcat как Apache TomEE , вот некоторые из пробелов, которые нам пришлось заполнить, чтобы наконец передать Java EE 6 TCK.

Не полный список, но некоторые основные моменты, которые могут быть неочевидны даже при существующих ответах.

Нет TransactionManager

Управление транзакциями определенно требуется для любого сертифицированного сервера. В любом веб-компоненте (сервлет, фильтр, слушатель, управляемый bean-компонент jsf) вы можете получить 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 SecurityContext, защита EJB, вход в систему JAAS и JAAC - все это концепции безопасности, которые по умолчанию не «подключаются» в Tomcat, даже если вы по отдельности добавляете библиотеки, такие как CXF, OpenEJB и т. Д.

Все эти API, конечно, предполагают совместную работу на сервере Java EE. Нам пришлось проделать довольно много работы, чтобы заставить все это взаимодействовать и сделать это поверх API Tomcat Realm, чтобы люди могли использовать все существующие реализации Tomcat Realm для управления своей "Java EE" безопасность. Это действительно безопасность Tomcat, просто она очень хорошо интегрирована.

JPA Integration

Да, вы можете поместить провайдера JPA в файл .war и использовать его без помощи Tomcat. При таком подходе вы не получите:

  • @PersistenceUnit EntityManagerFactory впрыск / поиск
  • @PersistenceContext EntityManager впрыск / поиск
  • EntityManager подключен к транзакционному пулу соединений
  • JTA-Managed EntityManager поддержка
  • Расширенные контексты персистентности

JTA-Managed EntityManager в основном означает, что два объекта в одной и той же транзакции, которые хотят использовать EntityManager, увидят оба одинаковых EntityManager, и нет необходимости явно передавать EntityManager. Все это «прохождение» сделано для вас контейнером.

Как это достигается? Просто, EntityManager, который вы получили из контейнера, является подделкой. Это обертка. Когда вы используете его, он ищет в текущей транзакции настоящий EntityManager и делегирует вызов этому EntityManager. В этом причина таинственного метода EntityManager.getDelegate(), поэтому пользователи могут получить real EntityManager, если они хотят, и использовать любые нестандартные API. Делайте это с большой осторожностью, и никогда не держите ссылку на делегата EntityManager, иначе у вас будет серьезная утечка памяти. Делегат EntityManager обычно сбрасывается, закрывается, очищается и сбрасывается по завершении транзакции. Если вы все еще держитесь за ссылку, вы предотвратите сборку мусора этого EntityManager и, возможно, всех данных, которые он содержит.

  • Всегда безопасно хранить ссылку на EntityManager, который вы получили из контейнера
  • Неверно хранить ссылку на EntityManager.getDelegate()
  • Будьте очень осторожны, обращаясь к EntityManager, который вы создали сами с помощью EntityManagerFactory - вы на 100% ответственны за его управление.

Интеграция CDI

Я не хочу чрезмерно упрощать CDI, но я считаю, что он слишком велик, и многие люди не смотрят серьезно - он включен в "когда-нибудь" список для многих людей :) Так что это просто пара основных моментов, о которых, я думаю, «веб-парень» хотел бы знать.

Вы знаете все, что вам нужно делать в обычном веб-приложении? Потянув вещи в и из HttpSession весь день? Использование String для ключа и непрерывного приведения объектов, которые вы получаете из HttpSession. Вы, вероятно, пошлите служебный код, чтобы сделать это для вас.

CDI также имеет этот код утилиты, он называется @SessionScoped. Любой объект, отмеченный @SessionScoped, помещается и отслеживается в HttpSession для вас. Вы просто запрашиваете инъекцию объекта в ваш сервлет через @Inject FooObject, и контейнер CDI будет отслеживать «реальный» экземпляр FooObject так же, как я описал отслеживание транзакций EntitityManager. Абракадабра, теперь ты можешь удалить кучу кода:)

Делаете какие-нибудь getAttribute и setAttribute на HttpServletRequest? Ну, вы можете удалить это тоже с помощью @RequestScoped таким же образом.

И, конечно, есть @ApplicationScoped для устранения вызовов getAttribute и setAttribute, которые вы, возможно, делаете на ServletContext

Чтобы сделать вещи еще круче, любой отслеживаемый объект может реализовать @PostConstruct, который вызывается при создании компонента, и метод @PreDestroy, который должен быть уведомлен, когда указанная "область действия" завершена (сеанс завершен, запрос окончен, приложение закрывается).

CDI может сделать намного больше, но этого достаточно, чтобы кто-то захотел переписать старое веб-приложение.

Некоторые разборчивые вещи

В Java EE 6 добавлены некоторые вещи, которые находятся в рулевой рубке Tomcats, но не были добавлены. Они не требуют больших объяснений, но объясняют большую часть «заполнения пробелов».

  • Поддержка @DataSourceDefinition
  • Поддержка Global JNDI (java:global, java:app, java:module)
  • Enum инъекция через @Resource MyEnum myEnum и
  • Инъекция класса через @Resource Class myPluggableClass и
  • Поддержка @Resource(lookup="foo")

Незначительные баллы, но может быть невероятно полезно определить DataSource в приложении портативным способом, обмениваться записями JNDI между веб-приложениями и иметь простую возможность сказать «ищите эту вещь и внедряйте ее»

Заключение * +1201 * Как уже упоминалось, не полный список. Нет упоминаний об EJB, JMS, JAX-RS, JAX-WS, JSF, валидации бинов и других полезных вещах. Но, по крайней мере, некоторые идеи о вещах часто упускаются из виду, когда люди говорят о том, что такое Tomcat, а что нет. Также помните, что то, что вы, возможно, считаете «Java EE», может не соответствовать фактическому определению. Благодаря веб-профилю Java EE сократилась. Это было преднамеренно в отношении "Java EE слишком тяжел, и мне все это не нужно". Если вы удалите EJB из веб-профиля, вот что у вас осталось: Java-сервлеты Java ServerPages (JSP) Java ServerFaces (JSF) API транзакций Java (JTA) API персистентности Java (JPA) Контексты Java и внедрение зависимостей (CDI) Проверка бобов Это чертовски полезный стек.

8 голосов
/ 06 ноября 2008

Если вам не нужен EJB, вам не нужен J2EE-сервер с полным стеком (коммерческий или нет).

Вы можете иметь большинство функций J2EE (таких как JTA, JPA, JMS, JSF) без сервера J2EE с полным стеком. Единственное преимущество j2ee с полным стеком состоит в том, что контейнер будет управлять всем этим от вашего имени декларативно. С появлением EJB3, если вам нужны управляемые контейнером сервисы, использование одного - это хорошая вещь.

У вас также может быть бесплатный сервер с полным стеком, такой как Glasfish, Geronimo или JBoss.

Вы также можете запускать встроенные службы J2ee-контейнеров со встроенным Glasfish, например, прямо внутри Tomcat.

Вам может понадобиться EJB-контейнер, если вы хотите использовать сессионные компоненты, объекты обработки сообщений, компоненты управления таймером, которыми вы управляете, даже при кластеризации и переключении при сбое.

Я бы посоветовал руководству рассмотреть возможность обновления в зависимости от необходимости. Некоторые из этих EJB-контейнеров могли бы просто использовать встроенный Tomcat в качестве своего веб-сервера, что дает!

Некоторые менеджеры просто любят платить за вещи. Попросите их рассмотреть возможность пожертвования городского приюта или просто пойти на BEA.

3 голосов
/ 06 ноября 2008

Если вас просят перейти на коммерческий сервер J2EE, причины могут быть не связаны со стеком J2EE, но не связаны с техническими соображениями.

Одна вещь, которую вы получаете с коммерческим предложением J2EE, которого вы не получаете с Tomcat, - это техническая поддержка.

Это может не учитываться для вас, в зависимости от уровня обслуживания, который должны удовлетворять ваши веб-приложения. Могут ли ваши приложения не работать, пока вы пытаетесь выяснить проблему с Tomcat, или это будет серьезная проблема?

2 голосов
/ 06 ноября 2008

По правде говоря, благодаря огромному массиву доступных пакетов и библиотек, EJB-контейнер предоставляет мало возможностей, которые нельзя добавить в современный контейнер сервлетов (ala Tomcat). Так что, если вам когда-либо понадобились какие-либо из этих функций, вы можете получить их «а-ля карт», так сказать, с затратами на процесс интеграции этой функции в ваше приложение.

Если вы не «пропускаете» ни одну из этих функций сейчас, то, с практической точки зрения, вам, вероятно, они не нужны.

Тем не менее, современные EJB-контейнеры действительно хороши и поставляются со всеми этими службами, предварительно интегрированными, что делает их несколько более простыми в использовании, если вы когда-либо захотите их. Иногда наличие функции поблизости и ее удобство достаточно, чтобы кто-то использовал ее потенциал в своем приложении, а не рассматривал процесс интеграции функции как препятствие для принятия.

С качеством бесплатных контейнеров EJB очень трудно представить, насколько покупка может быть вообще полезна, особенно если учесть, что у вас нет реального спроса на нее в данный момент.

Тем не менее, я призываю вас получить его, поиграть с ним и исследовать платформу. Glassfish очень прост в освоении и очень хорош, и он должен легко принимать ваши WAR как есть (или с очень незначительными изменениями).

Как правило, когда дело доходит до запуска Tomcat против контейнера EJB, вопрос в том, почему НЕ использовать его? Говоря конкретно о Glassfish, я нахожу его проще в использовании, чем Tomcat, и его основное отличие состоит в том, что он может иметь умеренно больший объем памяти (особенно для небольшого приложения), чем Tomcat, но в большом приложении вы даже не заметите, что , Для меня попадание памяти не имеет большого значения, для других это может быть проблемой.

И это дает мне единый источник всей этой приятной функциональности без необходимости сканировать сеть для стороннего варианта.

2 голосов
/ 06 ноября 2008

Стоимость не обязательно является недостатком, так как есть несколько бесплатных серверов J2EE, например JBoss и Glassfish.

Ваш вопрос предполагает, что (J2EE = Servlet + EJB + EAR) и, следовательно, нет смысла использовать что-либо, кроме контейнера сервлета, если вы не используете EJB или EAR. Это просто не тот случай, J2EE включает в себя гораздо больше, чем это. Примеры включают в себя:

  • JTA - API транзакций Java
  • JPA - API персистентности Java
  • JMS - спецификация обмена сообщениями Java
  • JSF - технология создания пользовательских интерфейсов из компонентов

Ура, Донал

...