what tutorial recursos produces inyeccion injection example español dependency dependency-injection websocket ejb java-ee-7 tyrus

dependency-injection - tutorial - java dependency injection example



Java EE 7: ¿Cómo inyectar un EJB en un WebSocket ServerEndpoint? (2)

(simplemente replanteando lo que escribí en el comentario para obtener esta pregunta de la lista "sin respuesta")

Debes revisar la github.com/tyrus-project/tyrus/tree/master/samples/cdi .

Muestra una lista de lo que puede hacer con la implementación actual. Siempre estamos abiertos a nuevos casos de prueba, pero hay algunos problemas con la especificación en sí misma: los ámbitos de solicitud estándar no funcionan para el tiempo de ejecución de WebSocket, porque maneja mensajes fuera de los métodos de servlets service / doFilter. Consulte java.net/jira/browse/WEBSOCKET_SPEC-196 y java.net/jira/browse/WEBSOCKET_SPEC-197 .

Para resumir mi proyecto fallido: mi clase @ServerEndpoint está empaquetada en un WAR junto con el archivo beans.xml. Mi WAR, a su vez, está empaquetado en un EAR y este archivo EAR es lo que se implementa en un servidor GlassFish 4 que usa internamente Tyrus.

¿Debería ser posible?

La specification WebSocket dice:

Los puntos finales de Websocket que se ejecutan en la plataforma Java EE deben tener soporte de inyección de dependencia completo como se describe en la especificación de CDI. Se requiere que las implementaciones de Websocket que forman parte de la plataforma Java EE admitan la inyección de campo, método y constructor utilizando javax.inject. Inyecte la anotación en todas las clases de punto final de websocket, así como el uso de interceptores para estas clases.

Lo único que puedo entender de este párrafo es que inyectar un Enterprise JavaBean en un WebSocket no debería ser una ciencia de cohetes. Sin embargo, para mí, haga lo que haga, no funciona. Creo que, de manera más intuitiva, solo se debe prefijar un campo de instancia de punto final de servidor con la anotación @EJB o @Inject , pero ninguna de estas anotaciones funciona. La variable será nula.

¿Ya es un problema conocido?

Una source Internet dice un poco crípticamente que "debido a un error" debe usar la inyección del constructor. Vi que había agregado la anotación @Named al punto final del servidor. Utilicé el famoso patrón de copiar y pegar e hice exactamente lo que hizo, con y sin la anotación @Named, y todavía no funciona. De hecho, mi constructor anotado @Inject nunca se llama!

La guía del usuario de Tyrus dice que se pueden mezclar cualquiera de las famosas anotaciones de declaración de bean de sesión con el punto final del servidor ( @Stateful , @Stateless y @Singleton ). Así lo hice, todavía la inyección no pasa. No importa si uso la anotación @Inject o @EJB.

Y eso es extraño, porque el libro Java EE 7 Developer Handbook dice tener un ejemplo funcional en la página 27 y la página 28 basado en el mismo enfoque. El autor Peter Pilgrim anota su punto final de servidor @Stateless . Luego usa @Inject para hacer la inyección. Él dice:

En Java EE 7 también debemos declarar [nuestro punto final del servidor] como un EJB sin estado con @Stateless para inyectar [otro EJB] como una dependencia. (Esto es una consecuencia de la especificación de Java para WebSocket 1.0). Tenga en cuenta que podemos usar @ javax.annotation.Inject de CDI.

De acuerdo, dice que debemos usar una anotación @Stateless y "notas" que se pueden usar @Inject. Para mí, suena completamente extraño que "debemos" usar una anotación @Stateless en un punto final del servidor que, según la especificación, es todo lo demás que sin estado (!). He leído en otras partes de Internet que usar @Inject en lugar de @EJB debería ser una solución. Peter "señala" que "podemos usar" @Inject pero huele a pescado, como si nunca hubiera conseguido que @EJB funcionara y ahora trata de huir de la responsabilidad.

Bueno, sea cual sea la razón ("error" o "consecuencia de la especificación"), no pude hacer que mi inyección de dependencia funcionara con la combinación vívida de anotaciones que usé en la clase de punto final o en el campo de instancia.

La mejor solución

Es usar programáticamente una búsqueda JNDI, pero se ve fea y debe evitarse.


Para mi. anotando el websocket con @Stateful y la declaración del objeto EJB con @EJB hizo el trabajo.

@Stateful @ServerEndpoint(value = "/profileregistration") public class ProfileRegistrationEndpoint { @EJB private ProfileRegistration profileRegEJB; .... }