I don't understand why CDI use of injection doesn't work with websockets, using undertow.
Below is the code I have for a simple websocket endpoint.
@ServerEndpoint("/")
public class TestWebSocketEndpoint {
@Inject
private RetrieveAccessor retrieveAccessor;
private final Logger logger = Logger.getLogger(this.getClass().getName());
@OnOpen
public void onConnectionOpen(Session session) {
logger.info("Connection opened ... " + session.getId());
}
@OnMessage
public String onMessage(String message) {
if (!message.isEmpty()) {
return message;
}
System.out.println("RETRIEVE BEAN -> " + retrieveAccessor);
if (retrieveAccessor != null) {
return "BEAN NOT NULL";
}
return ":(";
}
@OnClose
public void onConnectionClose(Session session) {
logger.info("Connection close .... " + session.getId());
}
}
Of course the issue is that the injected property is null. I have no problems of course using the rest side of things for this deployment and injection of the stateless bean described below. Is there a work around for this, what are the problems I could run into if I just init properties I need that are beans? Because that definitely works.
RetrieveAccessor retrieveAccessor = new.... {code}
An easy way to get injection working on your @ServerEndpoint annotated classes is to set a custom configurator that handles the creation of your endpoint instance by overriding the getEndpointInstance(Class endpointClass) method to instantiate with CDI.
https://tyrus.java.net/documentation/1.13/user-guide.html#d0e464
Annotated endpoint:
@ServerEndpoint(value = "/", configurator = CDIEndpointConfigurator.class)
public class TestWebSocketEndpoint {
...
}
Custom configurator:
public class CDIEndpointConfigurator extends ServerEndpointConfig.Configurator {
@Override
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
return CDI.current().select(endpointClass).get();
}
}