How to fix NPE during WebSocketFactory.Upgrade () on embedded Jetty 8.1.12

I am trying to run the Cometd websocket server in an automated warfare, which runs jetty 8.1.12 in embedded mode. I am able to run all other web applications 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 other posts and I think it is different.

I have 2 A maven project, one uses the maven-shades plugin to build a super jar that contains jetty-server 8.1.12, and the other contains the first jar as a war overlay. The overlay puts all jetty-server classes in the root directory of the war , So it can be run with “java -jar my.war”. Because Comet also needs jetty for websockets, so I make sure that all dependencies and jars in the WEB-INF/lib directory are 8.1.12. Therefore, the whole There is only one server and its dock 8.1.12 in the process. All other posts/problems are because of non-jumping or non-websocket container or non-http connection, but this is 1 00% jetty 8.1.12 and it works fine when deploying webapp using a standalone external jetty 8.1.12 instance.

Uberjar dependency from maven-shades (for embedded dock self-war war)

p>

[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:jet ty-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

The following is the code to run the 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();< br /> context.setServer(server);
context.setContextPath("/");

ProtectionDomain protectionDomain = Main.class.getProtectionDomain();
URL location = protectionDomain .getCodeSource().getLocation();
context.setWar(lo cation.toExternalForm());

server.setHandler(context);
server.start();
System.in.read();
server. stop();
server.join();

libs in 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

This problem may be related to the HttpConnection shared between the web application and the closed jetty server (I have read about HttpConnection-ThreadLocal and osgi The post) is related to the class loading problem between jetty classes. These two classes are actually in these two places, but I can’t find a way to separate them because they are needed in both places. /p>

Maybe there is a way for Jetty to share its class loaded classes with the webapp class loader? At this point, I have no idea and don’t know what I will try next. What should I do to make it work?

That’s it. Comparing the exact difference between an external jetty server (which works) and an embedded configuration After the difference, I was able to achieve this. It requires a bit of trial and error, and it is not very obvious, so I am sharing what I have done for others.

First of all, I am in WEB-INF/ The only jetty needed in lib is this:

jetty-util-8.1.12.v20130726.jar

All other embeddings I have outside Container. Even if this jar exists in the server classpath, the application will not load. The only feasible way is if I only add that jar to the /lib directory. This leads me to the next error:

java.lang.IllegalStateException: Websockets not supported on blocking connectors
at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:237)
at org.eclipse.jetty.websocket.WebSocketFactory.acceptWebSocket(WebSocketFactory.java:396)
at org.cometd.websocket.server.WebSocketTransport.handle(WebSocketTransport.java:157)

Note that it has passed NPE, this is progress. Then by looking at the log line in another working Jetty server, and a little reading of the non-blocking connector, I used this connector instead of SocketConector:

import org.eclipse.jetty.server.nio.SelectChannelConnector;
.. .
SelectChannelConnector connector = new SelectChannelConnector();

These two very simple The changes make me excited.

I am trying to run the Cometd websocket server in an automated war, which runs jetty 8.1.12 in embedded mode. Able to run all other web applications in 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 other posts and I think it is different .

I have 2 maven projects, one uses the maven-shades plugin to build a super jar containing jetty-server 8.1.12, and the other contains the first jar as a war coverage. The coverage will all The jetty-server class is placed in the root directory of the war, so it can be run with “java -jar my.war”. Because Cometd also needs jetty for websockets, so I make sure all the dependencies in the WEB-INF/lib directory And the jar are both 8.1.12. So there is only one server and its jetty 8.1.12 in the whole process. All other posts/problems are because of non-jumping or non-websocket container or non-http connection, but this is 100% j etty 8.1.12 and it works fine when deploying the webapp using a separate external jetty 8.1.12 instance.

The dependency of uberjar from maven-shades (for embedded dock self-war 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-clie nt: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

The following is the code to run the 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.toE xternalForm());

server.setHandler(context);
server.start();
System.in.read();
server.stop( );
server.join();

libs in 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

This question feels like it may be related to the HttpConnection shared between the web application and the closed jetty server (I have read posts about HttpConnection-ThreadLocal and osgi) The problem of class loading between jetty classes is related. These two classes are actually in these two places, but I can’t find a way to separate them, because they are needed in both places.

Maybe there is a way for Jetty to share its class loaded classes with the webapp class loader? At this point, I have no idea and don’t know what I will try next. What should I do to make it work?

That’s it. After comparing the exact difference between the external jetty server (which works) and the embedded configuration, I was able to achieve this. It takes a bit Trial and error, and it is not very obvious, so I am sharing what I have done for others.

First of all, the only dock I need in WEB-INF/lib is this:

p>

jetty-util-8.1.12.v20130726.jar

All other embedded containers I have outside. Even if this jar exists in the server classpath , The application will not load. The only feasible way is if I only add that jar to the /lib directory. This leads me to the next error:

 java.lang.IllegalStateException: Websockets not supported on blocking connectors
at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:237)
at org.eclipse.jetty.websocket.WebSocketFactory. acceptWebSocket(WebSocketFactory.java:396)
at org.cometd.websocket.server.WebSocketTransport.handle(WebSocketTransport.java:157)

Note that it has passed NPE, this is progress. Then By looking at the log lines in another working Jetty server, and a little reading of the non-blocking connector, I used this connector instead of SocketConector:

import org.eclipse .jetty.server.nio.SelectChannelConnector;
.. .
SelectChannelConnector connector = new SelectChannelConnector();

These two very simple changes make me excited.

Leave a Comment

Your email address will not be published.