Amar
Amar

Reputation: 763

Deploy webapps and websockets in jetty

I have embedded Jetty into my application. I have one webapp and I successfully deployed that webapp in the Jetty. Now I got another requirement on Websockets. I followed this link for deploying websockets in Jetty. After deploying the Websockets into my server the first webapp is not working (the home page is not opening). Here is the image

enter image description here

Here is the code (Its very hard to paste the whole code here. So I am pasting the webapp and websocket deployment code).

Webapp Deployment:

List<Handler> handlersList = new ArrayList<Handler>();
WebAppContext webAppContext = new WebAppContext();
webAppContext.setResourceBase(webApp.appDir);
webAppContext.setDescriptor(webApp.appDir + "/WEB-INF/web.xml");
webAppContext.setContextPath(webApp.contextPath);
webAppContext.setParentLoaderPriority(true);
// webAppContext.setWar(webApp.appDir);
webAppContext.setVirtualHosts(webApp.hostName);
handlersList.add(webAppContext);
argNewServer.setHandler(handlersList);

WebSocket Deployment:

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/echo");
argServer.setHandler(context);

// Initialize javax.websocket layer
ServerContainer wscontainer;
try {
    wscontainer = WebSocketServerContainerInitializer.configureContext(context);
    // Add WebSocket endpoint to javax.websocket layer
    wscontainer.addEndpoint(WebSocketServer.class);
} catch (ServletException | DeploymentException e) {
    throw new RuntimeException("Exception while adding websocket endpoint: ", e);
}

WebSocketServer.java:

package com.tdg.chat;

import java.io.IOException;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/events/")
public class WebSocketServer {
    @OnOpen
    public void onWebSocketConnect(Session sess) {
        System.out.println("Socket Connected: " + sess);
    }

    @OnMessage
    public void onWebSocketText(Session argSession, String argMessage) throws IOException {
        System.out.println("Received TEXT message: " + argMessage);
        argSession.getBasicRemote().sendText("From Server: ");
    }

    @OnClose
    public void onWebSocketClose(CloseReason reason) {
        System.out.println("Socket Closed: " + reason);
    }

    @OnError
    public void onWebSocketError(Throwable cause) {
        cause.printStackTrace(System.err);
    }
}

If I include the aforementioned websocket code the actual webapp is not working, but the websocket code is working.

So how to deploy a webapp and websocket in one Jetty server?

Updated:

I tried to include the Websockets in the current webapp itself but I am getting the following exception.

java.lang.NullPointerException: null at org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:65) ~[javax-websocket-server-impl-9.3.6.v20151106.jar:9.3.6.v20151106] at com.tdg.daemon.server.RiseServer.getWebappHandlers(RiseServer.java:122) ~[classes/:na] at com.tdg.daemon.server.RiseServer.addWebApps(RiseServer.java:77) ~[classes/:na] at com.tdg.daemon.server.RiseServer.init(RiseServer.java:59) ~[classes/:na] at com.tdg.daemon.server.RiseServerConfiguration.build(RiseServerConfiguration.java:475) ~[classes/:na] at com.tdg.daemon.server.launcher.DefaultTdgServerLauncher.start(DefaultTdgServerLauncher.java:78) [classes/:na] at com.tdg.daemon.server.launcher.DefaultTdgServerLauncher.main(DefaultTdgServerLauncher.java:140) [classes/:na] java.lang.NullPointerException at org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(WebSocketServerContainerInitializer.java:65) at com.tdg.daemon.server.RiseServer.getWebappHandlers(RiseServer.java:122) at com.tdg.daemon.server.RiseServer.addWebApps(RiseServer.java:77) at com.tdg.daemon.server.RiseServer.init(RiseServer.java:59) at com.tdg.daemon.server.RiseServerConfiguration.build(RiseServerConfiguration.java:475) at com.tdg.daemon.server.launcher.DefaultTdgServerLauncher.start(DefaultTdgServerLauncher.java:78) at com.tdg.daemon.server.launcher.DefaultTdgServerLauncher.main(DefaultTdgServerLauncher.java:140) [] 12/02/2015 17:50:06.985 [main - ] INFO c.t.d.s.l.DefaultTdgServerLauncher - RiseServer started on port 80 and 443.

Upvotes: 3

Views: 2861

Answers (2)

Amar
Amar

Reputation: 763

@Joakim Erdfelt, Its my mistake and I agree with your second point. What I did is, First I added my webapp handler to the server and then I added websocket handler to the server (Based on aforementioned example).

argNewServer.setHandler(webAppContext);
argNewServer.setHandler(context);

As you mentioned in the second point once if we set the handlers to the server we can't modify the things in the server. That's true, I modified my code like I added all my handlers in single shot. Then my webapp starts working and my websocket is also working. Here is the modified code

List<Handler> handlersList = new ArrayList<Handler>();
handlersList.add(webAppContext);
handlersList.add(context);
argNewServer.setHandler(handlersList);

Thank you you very much @Joakim Erdfelt.

Upvotes: 0

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49545

The WebSocketServerContainerInitializer.configureContext() requires knowledge about the Server that it will be run under.

There's 2 ways to accomplish this, choose either approach before you call WebSocketServerContainerInitializer.configureContext()

  1. Add the ServletContextHandler to the Server instance via its Server.setHandler(Handler) call before you attempt to configure the context. (the ServletContextHandler can be part of a larger Handler tree and this will work). The mere act of calling Server.setHandler(Handler) will populate the Server reference for all of the Handler instances you have declared. (This is the recommended approach)
  2. Manually call ServletContextHandler.setServer(server) - but be careful to not swap out/change the Server instance you use later in Server.setHandler(Handler) call. Also, once you do this, you cannot change things in the Server, such as the Thread Pool, Executors, Buffer Pools, Schedulers, etc. (This is an undesirable, but functional, approach)

Upvotes: 3

Related Questions