четверг, 11 декабря 2014 г.

Зачем нужны EJB

Предлагаю подискутировать. К сожалению на форуме javatalks.ru мое сообщение не вызвало интереса, может быть это признак неготовности аудитории к использованию промышленных решений, но так как последние годы в блоге я писал все больше как раз про такие подходы к решению задач, то возможно у моих читателей тема вызовет больше интереса.

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

Основной альтеративой EJB долгие годы является Spring Framework, который, однако, ни одну из вышеперечисленных задач не решает самостоятельно. Есть отвевления в проекте Spring Framework, отвечающие за модульность (Spring DM), безопасность (Spring Security), и т.д. но при этом нет реализации Single Sign-On (SSO), нет менеджера глобальных и распределенных транзакций, Spring Framework умеет только подключаться к существующим, предоставляемым как правило полноценными серверами приложений. Что касается кластеризации, то она в Spring Framework как таковая отсутствует, т.е. можно развернуть две копии приложения на каком-нибудь Tomcat, но за репликацию сессий, если таковые используются, будет отвечать сам контейнер сервлетов, а за вызов обеих копий по протоколу HTTP - какой-нибудь внешний балансировщик нагрузки, сам фреймворк при этом не причем. При использовании же EJB мы, во-первых, не привязаны к протоколу HTTP и внешнему балансировщику нагрузки: EJB-клиент является сам себе балансировщиком, да к тому же работает по более быстрому протоколу; во-вторых же, обеспечивается прозрачное для клиента восстановление после сбоев: если вы отметили метод сессионного компонента как идемпотентный, то в случае сбоя вызов от клиета (сервлета или RMI/IIOP-клиента) автоматически будет перенаправлен на экземпляр компонента, расположенный на другом сервере. Клиент тем самым даже не заметит проблемы.

Т.е. Spring Framework выступает топором в одноименной каше: он очень крут, но для решения задачи нужно сыпануть в варево порцию библиотек, перемешать и молиться, чтобы ничего не сбоило и не конфликтовало друг с другом. JAR-Hell. Так же носить с собой ворох библиотек в WEB-INF/lib - удовольствие ниже среднего.

Основными недостатками EJB считают многословность, трудоемкость для разработчика, большие XML-дескрипторы и т.д. Но это все давно в прошлом. Начиная с EJB 3.0, это уже практически новая технология, лаконичная, активно использующая аннотации как средство описания метаданных. Появившиеся в EJB 3.1 и Java EE 6 нововведения делают альтернативные средства, такие как Spring Framework, Google Guice, Tapestry IoC и т.д. ненужными. Да, когда-то они решали свою задачу: облегчать программисту доступ к низкоуровневым сервисам, минуя EJB, но теперь данная задача не актуальна. У нас в сервере приложений из коробки доступны: IoC-контейнер, менеджер глобальных и распределенных транзакций, декларативные настройки безопасности, огромное количество различных провайдеров безопасности (хранение данных пользователей хоть в LDAP, хоть в БД, хоть в специализированных решениях, авторизация хоть по паролю, хоть по сертификату, контроль сертификатов, цепочки отзыва, Single Sign-On (SSO), сквозная по всем приложениям авторизация и аутентификация, когда сервер приложений определяет, имеет ли право пользователь, вошедший по сертификату, писать в очередь A и читать данные из БД под пользователем B, гибкая система прав доступа, когда ровно в 18:00 администратор превращается в тыкву и т.д.), полноценная кластеризация, работа с очередями сообщений и внешними информационными системами. И EJB - самый простой с точки зрения программиста способ воспользоваться данным богатством, при этом ваш код будет по прежнему состоять из старых-добрых POJO, использовать JPA или JDBC и вызываться из любого веб-фреймворка, который вам нравится.

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

UPD: по мотивам статьи разгорелась интересная дискуссия.

UPD2: Сделал небольшой бенчмарк: EJB показывает на 10 - 15% лучшую производительность нежели Spring Framework.


Понравилось сообщение - подпишитесь на блог

16 комментариев:

Rage Steel комментирует...

Разумеется нужны. Для меня EJB 3.0 после Spring'а были просто откровением — замечательная технология. JavaEE сервер приложений — замечательная штука, предоставляющая много разных сервисов, в отличие от Spring'а — простого набора библиотек, которые ещё нужно друг с другом связать.
Для своего будущего проекта возьму TomEE.

Pavel Samolisov комментирует...

Спасибо за отклик! Если не трудно, опишите почему выбрали именно TomEE?

Rage Steel комментирует...

Выбор пока предварительный. Возможно в процессе эксплуатации что-то поменяется.
Использовать какие-то особенности конкретных реализаций JavaEE именно от TomEE я не планирую.
Хочется OpenSource, чтобы можно было сделать нужное без Reverse Engineering'а (а то как-то мне пришлость прикручивать Mojarra 2.0 к WAS 7.0, чтобы ManagedBean'ах работала инъекция @EJB — без reverse engeneering правда всего одного класса не обошлось)
Он мне кажетчя эдаким конструктором, который можно легко подстроить под себя и оставить только нужные компоненты. Лично мне пока нужно:
* Веб-сокеты;
* JPA 2.1 и EJB;
* Возможно JSON.
Соответственно для получения JPA 2.1: OpenJPA заменяется на EclipseLink.
На JBoss особо пристально не смотрел, как у него с выкидыванием лишнего, Glassfish кажется совсем монолитным.
Если рассматривать коммерческие варианты, то я бы взял WebSphere Liberty Profile. Кажется, что из него ещё проще «слепить» минимально необходимую сборку.

mike konovalov комментирует...

Хорошая попытка, EJB...
Но нет!

Pavel Samolisov комментирует...

А аргументировать?

Евгений Конурбаев комментирует...

Правильно я понимаю, что EJB и OSGi несовместимы? Т.е. - это абсолютно разный стиль построения приложения?

Pavel Samolisov комментирует...

Некоторые сервера приложений поддерживают "дружбу" данных технологий но как оно ведет себя в продакшне я не знаю. http://docs.oracle.com/cd/E18930_01/html/821-2418/gkqff.html#gkvcj

plumqqz комментирует...

Спринг вообще довольное странное явление - эклектичный набор библиотек сомнительной ценности.
В действительности альтернативой EJB может служить либо Oracle, либо DB2; причем, думаю, по производительности последние изрядно переплюнут (хотя бы из тех соображений, что не надо гонять данные между базой и сервером приложений).
Что касается аннотаций - мне не удавалось заставить MDB из глассфиша (EJB 3.0) слушать Websphere MQ только аннотациями - а вот с дескриптором оно спокойненько заработало; с другой стороны не такие уж они и страшные, эти дескрипторы.
С другой стороны, если надо соединять разнородные платформы то особых альтернатив EJB нет; но, опять же, как вы отметили, есть "признак неготовности аудитории к использованию промышленных решений"; а если за все время существования EJB массовая публика так и не подготовилась, то разумно ожидать, что и не подготовится.
В общем, на мой взгляд, технология хорошая, но не массовая.

Pavel Samolisov комментирует...

Большое спасибо за столь развернутый и аргументированный комментарий.

Позволю себе не согласиться только насчет непопулярности EJB. На мой взгляд это несколько локальное явление, впрочем у России всегда был свой уникальный путь, но и то постепенно наблюдается улучшение ситуации. После выхода EJB 3.1 в уже далеком 2009-м году все больше и больше проектов строится на данной технологии (естественно там где это уместно, т.е. не для сайтов-визиток). Наконец-то и до нас доходит важность использования промышленных решений, благодаря усилиям вендоров и на локальном рынке все более популярными становятся промышленные сервера приложений. Конечно и на WebSphere можно развернуть Spring-приложение, но зачем, если есть EJB? Для молодых разработчиков Spring Framework вообще становится каким-то легаси-решением. Да и сами разработчики и евангелисты Spring это понимают, отсюда и их забавы с "микросервисами" и прочими баззвордами, мол мы уже не просто альтернатива EJB, мы вооот что можем!

Dmitry Katsubo комментирует...

"В Spring Security нет реализации Single Sign-On (SSO)" – это верно, но поддержка SSO (хотя, какой именно протоков вы имеете в виду?), в частности, Kerberos / Negotiate, есть в Java 6 SE. Она предоставляет интерфейс через JAAS, поддержка которого есть в Spring Security (пакет org.springframework.security.authentication.jaas).

Pavel Samolisov комментирует...

Имел в виду SAML.

Dmitry Katsubo комментирует...

В целом мне по душе ваша позиция насчёт J2EE (также высказанная в [1], [2], [3]). Но есть и ложка дёгтя. Из собственного опыта: перед командой стояла задача портировать приложение с сервера WebSphere на JBoss. Казалось бы, оба сервера реализуют те же стандарты, и приложение должно было просто запуститься на новой платформе без изменений. Однако миграция заняла 6(!) месяцев. Чуть меньше заняла миграция с JBoss4 на Jboss6...

"...не сбоило и не конфликтовало друг с другом. JAR-Hell. Так же носить с собой ворох библиотек в WEB-INF/lib - удовольствие ниже среднего"

Проблема с commons-collections может "всплыть" на любом проекте, EJB-подход от этого не застрахован. Единственное, что, быть может, реже (с оговоркой, что приложение использует то, что предоставляет сервер, то есть, фактически написанное под определённый архитектурный шаблон). Попытки использовать что-то "извне" (например, в доменных областях, где нужна обработка звука/изображений) неизбежно ведут к распуханию "lib". С другой стороны, Spring-проекты тоже часто следуют одному и тому же "клише" (я про изобилие статей типа "Построим Web приложение на Vaadin+Spring+Hibernate за 5 минут"), то есть, эти связки обкатаны и проверены.

А преимущество следующее: приложение на Spring (лучше скажем "не-EJB") деплоится на Tomcat/Jetty/JBoss и работает везде одинаково (по крайней мере функционально), то есть, заказчик (или покупатель) не привязан к конкретной платформе. Для небольших приложений (например, JIRA или Jenkins), это, по-моему, плюс: их можно скачать с сайта и установить на любую платформу или запустить "из коробки".

[1] http://samolisov.blogspot.nl/2014/08/java-ee-6.html
[2] http://samolisov.blogspot.nl/2015/10/spring-framework.html
[3] http://samolisov.blogspot.nl/2012/07/spring-vs-javaee.html

Pavel Samolisov комментирует...

Ого! Большое спасибо за столь подробный и развернутый комментарий.

Позволю себе высказать мнение. В первую очередь по поводу сложности/легкости миграции. У меня сложилось впечатление, что это проблема больше сервера приложений JBoss, нежели Java EE, точнее - того, как спецификации реализованы в данном сервере приложений. В сети есть несколько описаний трудностей миграции в том числе и между думя последовательными версиями данного сервера приложений, например JBoss EAP 5 to JBoss EAP 6 Upgrade - Customer Story. Так же справедливости ради отмечу, что EJB может быть не единственным проблемным местом в процессе миграции, в моем опыте проблемным местом были, банальнейшие JSP, т.е. даже спринговое приложение может не заработать на другом сервере без обработки напильником.

По поводу пакетного распространения приложений вида "скачал и запустил", здесь интересен WebSphere Liberty Profile - очень маленький (ядро - 11 МБ, всего на 1.5 МБ больше Apache Tomcat, общий объем инсталляции зависит от установленных, т.е. нужных вам, компонентов, реализующих спецификации), модульный, т.е. к рантайму подключаются только те компоненты, реализующие спецификации Java EE, которые нужны именно вам, быстро стратующий - запуск небольшого приложения осуществляется за 1.5 - 2 с. При всем при этом, Liberty Profile - полноценный сервер приложений, являющийся первым в мире готовым для промышленной эксплуатации (production ready) сервером, в котором реализована полная поддержка Java EE 7. Под готовностью к промышленной эксплуатации я понимаю поддержку вендром (одним из известнейших на рынке), кластеризацию с расчетом на сотни и тысячи узлов, встроенный механизм очередей сообщений, в общем все то, о чем написано в заметке, на которую вы любезно дали ссылку - [2].

Юрий Давыдов комментирует...

Добрый день! Вопрос не совсем в тему, но может быть подскажете :) есть ли возможность обновить версию EJB до 3.2 в Jdeveloper 12c?

Pavel Samolysov комментирует...

Здравствуйте! К сожалению, не подскажу.

Юрий Давыдов комментирует...

Эххх, жалко! Ну всё равно спасибо за ответ! Доброго дня!

Отправить комментарий

Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!