如何在嵌入式Jetty 8.1.12上的WebSocketFactory.upgrade()期间修复NPE

时间:2013-09-09 12:40:53

标签: websocket jetty embedded-jetty cometd

我正在尝试在自动执行的战争中运行Cometd websocket服务器,该战争在嵌入模式下运行jetty 8.1.12。我能够以这种方式运行所有其他Web应用程序,但对于websocket案例,我收到此错误:

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)

我已经阅读了所有其他帖子,我认为这是不同的。

我有2个maven项目,一个使用maven-shades插件构建包含jetty-server 8.1.12的超级jar,另一个包含第一个jar作为war覆盖的另一个。覆盖将所有jetty-server类放在战争的根目录中,因此它可以使用“java -jar my.war”运行。因为Cometd还需要用于websockets的jetty,所以我确保WEB-INF / lib目录中的所有依赖项和jar都是8.1.12。因此,整个过程中只有一台服务器及其码头8.1.12。所有其他帖子/问题都是因为非跳船或非websocket容器或非http连接,但这是100%jetty 8.1.12并且当使用独立的外部jetty 8.1.12实例部署webapp时工作正常。

来自maven-shades的uberjar的依赖性(用于嵌入式码头自我战争)

[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

以下是运行嵌入式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();

webapp WEB-INF / libs中的lib:

 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

问题感觉可能与在Web应用程序和封闭的jetty服务器之间共享的HttpConnection(我读过关于HttpConnection-ThreadLocal和osgi的帖子)之类的jetty类之间的类加载问题有关。这两个类实际上都在这两个地方,但我找不到分开它们的方法,因为它们在两个地方都是需要的。

也许有一种方法让jetty与webapp类加载器共享其类加载的类?在这一点上,我已经没有想法,也不知道接下来我会尝试什么。我该怎么做才能让它发挥作用?

3 个答案:

答案 0 :(得分:1)

搞定了。在比较外部jetty服务器(可以工作)和嵌入式配置之间的确切差异之后,我能够实现这一点。它需要一点试验和错误,而且不是很明显,所以我正在分享我为别人做的事情。

首先,我在WEB-INF / lib中需要的唯一码头是这个:

jetty-util-8.1.12.v20130726.jar

我在外面拥有嵌入式容器的所有其他人。即使这个jar存在于服务器类路径中,该应用程序也不会加载。唯一可行的方法是,如果我只将那个jar添加到/ lib目录中。这导致我出现了下一个错误:

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)

注意它已经过了NPE,这是进步。那么通过查看其他工作Jetty服务器中的日志行,以及对非阻塞连接器的一点阅读,我使用了这个连接器而不是SocketConector:

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

这两个非常简单的变化让我开始运作。

答案 1 :(得分:0)

我遇到了同样的问题,我正在尝试依靠atmosphere构建的应用程序而且我正在Jetty-9下运行应用程序。

我发现war/WEB-INF/lib中的Jetty罐子是:

jetty-continuation-7.6.7.v20120910.jar jetty-http-7.6.7.v20120910.jar jetty-io-7.6.7.v20120910.jar jetty-security-7.6.7.v20120910.jar jetty-server-7.6.7.v20120910.jar jetty-servlet-7.6.7.v20120910.jar jetty-util-7.6.7.v20120910.jar jetty-websocket-7.6.7.v20120910.jar

我切换到Jetty-8,问题就消失了。

答案 2 :(得分:0)

在将tomcat与vaadin 7和大气一起使用时,出现此错误。该错误对应用程序的良好行为没有影响,但不时弹出。

java.lang.NullPointerException
at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:238)

通过从类路径中删除gwt-dev-2.7.0.vaadin4.jar解决了该问题。看来我还是不需要它。