6

I am trying to develop a Java EE 7 web application that uses a websocket endpoint and deploy it on a Jetty server.

The application has the following structure:

Game/
  src/
    main/
      java/
        game/
          WebSocketEndpoint.java
      webapp/
        index.html
        scripts/
          variousjavascriptstuff.js
        WEB-INF/
          beans.xml
          web.xml

In the beans.xml file:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
   bean-discovery-mode="annotated">

WebSocketEndpoint is annotated properly and works fine with Netbeans/Glassfish4, however, the application must be deployed on a Jetty server.

So, my question - How do I map the websocket endpoint to the URL /game in the web.xml file? I have found a number of examples for mapping servlets, but I do not think that this will work for a server endpoint.

Or, is there a way to write a web.xml file for Jetty so that it automatically discovers ll annotated classes/methods (similar to the above beans.xml)

Kyle
  • 893
  • 1
  • 9
  • 20

1 Answers1

9

Assuming you have annotated game.WebSocketEndpoint using the JSR-356 techniques ...

Example:

package game;

import javax.websocket.server.ServerEndpoint

@ServerEndpoint("/game")
public class WebSocketEndpoint {

}

Then you have to do the following...

  1. Use Jetty 9.1+
  2. Enable the 'websocket' module (add --module=websocket to your start.ini or command line)

That will enable the websocket server classes + annotation scanning for websocket endpoints.

Note: that JSR-356 isn't meant to be mapped via the deployment descriptor (web.xml).

However, you can programmatically map your endpoints using one of the following techniques:

  1. Create a javax.servlet.ServletContextListener that manually adds endpoints via the javax.websocket.server.ServerContainer (see below for how)
  2. Create a javax.servlet.ServerContainerInitializer that manually adds endpoints via the javax.websocket.server.ServerContainer (see below for how)
  3. Create a javax.websocket.server.ServerAppliationConfig that returns the endpoints that you want to add.

Note: technique #2 and #3 both require class scanning for annotations (slow startup). technique #1 is fast startup.

How to Manually Add Endpoints

// Get a reference to the ServerContainer
javax.websocket.server.ServerContainer ServerContainer =
  (javax.websocket.server.ServerContainer)
  servletContext.getAttribute("javax.websocket.server.ServerContainer");
// Add endpoint manually to server container
serverContainer.addEndpoint(game.WebSocketEndpoint.class);
Joakim Erdfelt
  • 46,896
  • 7
  • 86
  • 136
  • what about for other containers? I like the manual configuration but i find it mind boggling that no were in the internet does someone mention how to get your contianer ( tomcat 8 ) to detect severendpoints. Isn't there a generic way? I don't like container specific solutions. – mjs Mar 11 '16 at 09:49
  • 1
    The code fragment above works also in Tomcat 8.5 (and probably in other Tomcats). In the javadoc of `javax.websocket.server.ServerContainer`, it is mentioned that this is a standard procedure to access the `ServerContainer` for "websocket enabled web containers" (see e.g. here: https://github.com/eclipse-ee4j/websocket-api/blob/master/api/server/src/main/java/javax/websocket/server/ServerContainer.java) – Remigius Stalder Sep 10 '18 at 08:23