Search code examples
tomcatjerseycdijava-websockettomcat9

Using CDI/injection in Tomcat Websocket / Serverendpoint


i am using tomcat 9.0.4 and Java 1.8. In the same project, jersey is providing an webservice. I can use @Inject from the webservice classes without any problem. I am trying to get injection working from my websocket endpoint display below.

@ApplicationScoped
@ServerEndpoint("/endpoint")
public class ArchApi {

  @Inject RepClass injectedClass;

  @OnMessage()
  public String onMessage(byte[] data) {
       injectedClass.doThings("test");
  }

}

This is my CDI implementation:

    <dependency>
        <groupId>org.glassfish.jersey.inject</groupId>
        <artifactId>jersey-hk2</artifactId>
        <version>2.27</version>
    </dependency>

All i get is a java.lang.NullPointerException.

I found this feature request. So i think Injection is still not implemented in tomcat.

My questions:

  • How do i proper write my incomming data to my repository?
  • Is there another way to get Injection working?

At the moment i am thinking about a migration to glassfish, which should support injection from a Serverendpoint


Solution

  • You could use the following configurator to make CDI manage the endpoint classes:

    public class CdiAwareConfigurator extends ServerEndpointConfig.Configurator {
    
        public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
            return CDI.current().select(endpointClass).get();
        }
    }
    

    Then annotate your endpoint classes as following:

    @ServerEndpoint(value = "/chat", configurator = CdiAwareConfigurator.class)
    public class ChatEndpoint {
        ...
    }
    

    Depending on your CDI configuration, you may need to annotate the endpoint classes with @Dependent.


    Alternatively you could programmatically look up for a bean instance using:

    SomeSortOfBean bean = CDI.current().select(SomeSortOfBean.class).get();