WebSphere Liberty запускает несколько одноэлементных экземпляров EJB.

Я разрабатываю корпоративное приложение, упакованное в ухо. Ухо состоит из одного приложения Enterprise Bean (в банке), одного приложения JAX-RS (в войне) и одного веб-приложения (тоже в войне).

Дескриптор уха (application.xml) выглядит так:

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
    "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
    "http://java.sun.com/dtd/application_1_3.dtd">
<application>
  <display-name>myapp-ear</display-name>
  <module>
    <web>
      <web-uri>myapp-war-1.0.0-SNAPSHOT.war</web-uri>
      <context-root>/</context-root>
    </web>
  </module>
  <module>
    <web>
      <web-uri>myapp-rest-1.0.0-SNAPSHOT.war</web-uri>
      <context-root>/api</context-root>
    </web>
  </module>
  <module>
    <ejb>myapp-ejb-1.0.0-SNAPSHOT.jar</ejb>
  </module>
</application>

Приложение EJB содержит одноэлементный компонент EJB, аннотированный @Singleton, @LocalBean и @Startup, который содержит метод @Schedule.

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

Это соответствует документации http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html

НО: у меня есть аналогичное приложение, работающее на сервере WebSphere с полным профилем, которое не показывает такого поведения. Вместо этого для всего приложения Enterprise существует только один экземпляр.

Сервер WLP работает под управлением 17.0.0.1 с версией Java 1.8.0_101.

Вопрос, если это ошибка - или я упускаю какую-то важную настройку в WLP?


person danishrulez    schedule 10.05.2017    source источник


Ответы (3)


Класс не определяет уникальность EJB. Каждый EJB имеет уникальный идентификатор из трех частей, состоящий из <app name>/<module name>/<bean name>. Итак, если один и тот же класс упакован в 3 местах, то будет 3 отдельных определения EJB. Кроме того, вы можете упаковать класс EJB в одном месте, но все же иметь 3, если вы идентифицируете его как EJB из 3 отдельных файлов ejb-jar.xml (при условии, что класс находится в общем месте). Это верно для всех типов EJB, но одиночный элемент может сделать поведение более очевидным.

Это поведение одинаково как для Liberty, так и для полнопрофильной WebSphere. Если выясняется, что в полнопрофильном WebSphere поведение отличается, вероятно, это связано с другим ограничением в упаковке. Например, если вы упаковываете класс синглтона в WAR или JAR, содержащий файл ejb-jar.xml с metadata-complete=true, и этот файл не определяет синглтон как EJB, тогда он будет проигнорирован. Точно так же, если вы упаковываете синглтон в WAR-модуль версии 2.5 или старше, тогда WAR-модуль не будет поддерживать включение EJB, и синглтон будет проигнорирован.

person Tracy    schedule 10.05.2017
comment
Думаю, я недостаточно хорошо описал ситуацию: класс одноэлементного компонента упакован только в одном месте - внутри модуля EJB. Ни в одном из проектов нет ejb-jar.xm. Все EJB аннотированы. Другие модули используют аннотацию @EJB для внедрения сеансовых компонентов по мере необходимости и не определяют собственных компонентов EJB. - person danishrulez; 11.05.2017

Да!

Проблема оказалась в неправильно настроенной зависимости Maven от EJB-архива в pom.xml. То, что должно было быть ПРЕДОСТАВЛЯЕМОЙ зависимостью, было установлено как зависимость КОМПИЛЯЦИИ, и это заставило Maven упаковать банку EJB в два файла войны.

Я изменил его в обоих веб-приложениях — и синглтон теперь создается только один раз для всего уха.

Если кто-то еще борется с этой проблемой, убедитесь, что ваша зависимость создана следующим образом:

<dependency>
  <groupId>com.acme.myapp</groupId>
  <artifactId>myapp-ejb</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <type>ejb</type>
  <scope>provided</scope>
</dependency>
person danishrulez    schedule 11.05.2017

Похоже, вы действительно правильно читаете спецификацию - одноэлементные компоненты должны быть "по одному на приложение для каждой JVM".

Liberty, похоже, ведет себя в соответствии со спецификацией. Поведение, которое вы наблюдаете в традиционном WebSphere (также известном как полный профиль), скорее всего, связано с другой настройкой приложения/EJB или традиционной дополнительной функцией WebSphere, которая выходит за рамки спецификации, позволяя вам ограничивать одноэлементные EJB в нескольких приложениях.

person Andy Guibert    schedule 10.05.2017
comment
Единственное: чем больше я об этом думаю, документированная функциональность не имеет особого смысла, когда вы упаковываете целое приложение в ухо. Обычно вам нужен только один экземпляр — зачем еще упаковывать все вместе и использовать синглтон? - person danishrulez; 10.05.2017