I'm trying to run the Cometd websocket server within a self executing war which runs jetty 8.1.12 in embedded mode. I'm able to run all the other web apps this way, but for the websocket case I get this error:
java.lang.NullPointerException
at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:238)
at org.eclipse.jetty.websocket.WebSocketFactory.acceptWebSocket(WebSocketFactory.java:396)
at org.cometd.websocket.server.WebSocketTransport.handle(WebSocketTransport.java:157)
at org.cometd.server.CometdServlet.service(CometdServlet.java:166)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686)
I have read all the other posts and I think this is different.
I have 2 maven projects, one that builds an uber jar containing jetty-server 8.1.12 using maven-shades plugin and the other one that includes that first jar as a war overlay. The overlay puts all the jetty-server classes in the root of the war so it can be run with "java -jar my.war". Because Cometd also needs jetty for websockets, I made double sure all of the dependencies and jars in the WEB-INF/lib dir are all 8.1.12 as well. So there is only one server and its jetty 8.1.12 throughout. All the other posts/questions are because of a non-jetty or non-websocket container or non-http connect, but this is 100% jetty 8.1.12 and the webapp works fine when deployed with a standalone external jetty 8.1.12 instance.
Dependencies for the uberjar from maven-shades (for the embedded jetty self-exe war)
[INFO] com.pgi.pulsar:pulsar-container:jar:1.0-SNAPSHOT
[INFO] +- org.eclipse.jetty:jetty-server:jar:8.1.12.v20130726:compile
[INFO] | +- org.eclipse.jetty.orbit:javax.servlet:jar:3.0.0.v201112011016:compile
[INFO] | +- org.eclipse.jetty:jetty-continuation:jar:8.1.12.v20130726:compile
[INFO] | \- org.eclipse.jetty:jetty-http:jar:8.1.12.v20130726:compile
[INFO] | \- org.eclipse.jetty:jetty-io:jar:8.1.12.v20130726:compile
[INFO] +- org.eclipse.jetty:jetty-servlet:jar:8.1.12.v20130726:compile
[INFO] | \- org.eclipse.jetty:jetty-security:jar:8.1.12.v20130726:compile
[INFO] +- org.eclipse.jetty:jetty-webapp:jar:8.1.12.v20130726:compile
[INFO] | \- org.eclipse.jetty:jetty-xml:jar:8.1.12.v20130726:compile
[INFO] +- org.eclipse.jetty:jetty-servlets:jar:8.1.12.v20130726:compile
[INFO] | +- org.eclipse.jetty:jetty-client:jar:8.1.12.v20130726:compile
[INFO] | \- org.eclipse.jetty:jetty-util:jar:8.1.12.v20130726:compile
[INFO] \- junit:junit:jar:4.8.2:test
Here is the code to run embedded jetty:
public class Main {
public static void main(String[] args) throws Exception {
Server server = new Server();
SocketConnector connector = new SocketConnector();
connector.setMaxIdleTime(1000 * 60 * 60);
connector.setSoLingerTime(-1);
String portValue = System.getProperty("pulsar.port");
int port = (portValue != null ? Integer.parseInt(portValue) : 8080);
connector.setPort(port);
server.setConnectors(new Connector[]{connector});
WebAppContext context = new WebAppContext();
context.setServer(server);
context.setContextPath("/");
ProtectionDomain protectionDomain = Main.class.getProtectionDomain();
URL location = protectionDomain.getCodeSource().getLocation();
context.setWar(location.toExternalForm());
server.setHandler(context);
server.start();
System.in.read();
server.stop();
server.join();
The libs in the webapp WEB-INF/libs:
jar tvf target/pulsar-websockets-1.0-SNAPSHOT.war | grep WEB-INF/lib/jetty | cut -b 36-100
WEB-INF/lib/jetty-client-8.1.12.v20130726.jar
WEB-INF/lib/jetty-continuation-8.1.12.v20130726.jar
WEB-INF/lib/jetty-http-8.1.12.v20130726.jar
WEB-INF/lib/jetty-io-8.1.12.v20130726.jar
WEB-INF/lib/jetty-jmx-8.1.12.v20130726.jar
WEB-INF/lib/jetty-server-8.1.12.v20130726.jar
WEB-INF/lib/jetty-util-8.1.12.v20130726.jar
WEB-INF/lib/jetty-websocket-8.1.12.v20130726.jar
WEB-INF/lib/jetty-xml-8.1.12.v20130726.jar
The problem feels like it might be related to a class-loading issue between jetty classes like HttpConnection (i read a post about HttpConnection-ThreadLocal and osgi) that are shared between the webapp and the enclosing jetty server. Those classes are in fact in both places, but I can't find a way to separate them since they are needed in both places.
Maybe there is a way to have jetty share its class-loaded classes with the webapp classloader? At this point, I've run out of ideas and don't know what I can try next. What can I do to get this to work?