Подтвердить что ты не робот

Java EE 7: Как внедрить EJB в WebSocket ServerEndpoint?

Подводя итог моему неудачному проекту: My @ServerEndpoint класс упакован в WAR вместе с файлом beans.xml. Моя WAR, в свою очередь, упакована в EAR, и этот файл EAR - это то, что развертывается на сервере GlassFish 4, который использует Tyrus внутри себя.

Должно ли быть возможно?

В спецификации WebSocket говорится:

Конечные точки Websocket, запущенные на платформе Java EE, должны иметь полный поддержка впрыска зависимостей, как описано в спецификации CDI. Для реализации платформы Java EE требуется реализация Websocket. поле поддержки, метод и впрыск конструктора с использованием javax.inject. Вводная аннотация во всех классах конечных точек websocket, а также использование перехватчиков для этих классов.

Единственное, что я могу понять из этого параграфа, это то, что инъекция Enterprise JavaBean в WebSocket не должна представлять собой ракетную науку. Однако для меня, что бы я ни делал, он не работает. Я считаю, что наиболее интуитивно нужно только префикс поля экземпляра конечной точки сервера с помощью аннотации @EJB или @Inject, но ни одна из этих аннотаций не работает. Эта переменная будет равна null.

Уже известная проблема?

Один интернет источник говорит немного загадочно, что "из-за ошибки" он должен использовать инъекцию конструктора. Я видел, что он добавил аннотацию @Named к конечной точке сервера. Я использовал знаменитый шаблон паттерна копирования и сделал именно то, что он сделал, с аннотацией @Named и без него, и он все еще не работает. На самом деле, мой конструктор аннотированных @Inject никогда не называется!

Руководство пользователя Tyrus говорит, что можно объединить всех известных аннотаций объявления bean с помощью конечная точка сервера (@Stateful, @Stateless и @Singleton). Так я и сделал, но инъекция не может произойти. Не имеет значения, использую ли я аннотацию @Inject или @EJB.

И это странно, потому что книга Java EE 7 Developer Handbook утверждает, что имеет рабочий пример на странице 27 и стр. 28 на основе того же подхода. Автор Питер Пилгрим комментирует свою конечную точку сервера @Stateless. Затем он использует @Inject для выполнения инъекции. Он говорит:

В Java EE 7 мы также должны объявить [нашей конечной точкой сервера] как апатриду EJB с @Stateless, чтобы ввести [другой EJB] в качестве зависимости. (Это является следствием спецификации Java для WebSocket 1.0.) Примечание. что мы можем использовать @javax.annotation.Inject из CDI.

Хорошо, поэтому он говорит, что должен использовать аннотацию @Stateless и "отмечает", что можно использовать @Inject. Для меня звучит совершенно странно, что мы "должны" использовать аннотацию @Stateless на конечной точке сервера, которая в соответствии со спецификацией - это все остальное, чем апатрид (!). Я читал в другом месте в Интернете, что использование @Inject вместо @EJB должно быть одним исправлением. Питер "отмечает", что "мы можем использовать" @Inject, но он пахнет рыжим, как будто он никогда не получал @EJB, чтобы работать вообще и теперь пытается бежать от ответственности.

Ну, какова бы ни была причина ( "ошибка" или "следствие спецификации" ), я не мог заставить свою инъекцию зависимостей работать с любым ярким сочетанием аннотаций, которые я использовал в самом классе конечной точки или в поле экземпляра.

Конечное исправление

Является программным использованием JNDI-поиска, но он выглядит уродливым и его следует избегать.

4b9b3361

Ответ 1

(просто пересказывая то, что я написал в комментарий, чтобы получить этот вопрос из списка "без ответа" )

Вы должны проверить образец/тест Tyrus CDI.

Он показывает список, что вы можете сделать с текущей реализацией. Мы всегда открыты для новых тестовых примеров, но есть некоторые проблемы с самой спецификацией - стандартные области запросов не работают для среды выполнения WebSocket, поскольку обрабатывают сообщения вне методов servlets/doFilter. См. WEBSOCKET_SPEC-196 и WEBSOCKET_SPEC-197.

Ответ 2

Для меня. аннотирование websocket с помощью объявления @Stateful и EJB объекта с помощью @EJB выполняло работу.

@Stateful
@ServerEndpoint(value = "/profileregistration")
public class ProfileRegistrationEndpoint {


@EJB
private ProfileRegistration profileRegEJB;
....
}