Подводя итог моему неудачному проекту: 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-поиска, но он выглядит уродливым и его следует избегать.