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

标签 websocket jetty embedded-jetty cometd

我正在尝试在以嵌入式模式运行 jetty 8.1.12 的自执行 war 中运行 Cometd websocket 服务器。我能够以这种方式运行所有其他网络应用程序,但对于 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 的 uber jar,另一个包含第一个 jar 作为 war 覆盖。覆盖将所有 jetty 服务器类放在 war 的根目录中,因此它可以使用“java -jar my.war”运行。因为 Cometd 还需要用于 websockets 的 jetty,所以我再次确保 WEB-INF/lib 目录中的所有依赖项和 jars 也是 8.1.12。所以只有一台服务器和它的 jetty 8.1.12。所有其他帖子/问题都是由于非 jetty 或非 websocket 容器或非 http 连接造成的,但这是 100% jetty 8.1.12,并且当使用独立的外部 jetty 8.1.12 实例部署时,webapp 工作正常。

来自 maven-shades 的 uberjar 依赖项(用于嵌入式 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

这是运行嵌入式 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 中的库:
 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

感觉这个问题可能与在 webapp 和封闭 jetty 服务器之间共享的 HttpConnection 等 jetty 类之间的类加载问题有关(我阅读了一篇关于 HttpConnection-ThreadLocal 和 osgi 的文章)。这些类实际上在两个地方都存在,但是我找不到将它们分开的方法,因为两个地方都需要它们。

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

最佳答案

得到它的工作。在比较了可以工作的外部 jetty 服务器和嵌入式配置之间的确切差异后,我能够让它工作。它需要一些反复试验,而且并不完全明显,所以我正在分享我为其他人所做的事情。

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

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();

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

关于websocket - 如何在嵌入式 Jetty 8.1.12 上的 WebSocketFactory.upgrade() 期间修复 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18698455/

相关文章:

reactjs - 使用react-scripts代理websocket不起作用

jquery 跨域认证

java - Jetty Websocket : can't find SimpleEchoSocket

java - jetty 9(嵌入式): Adding handlers during runtime

javascript - 如何使用 Laravel WebSockets 通过 Laravel 中的 WebSocket 将消息从客户端发送回服务器?

websocket - 多对多流共享状态的设计模式

java - 当我尝试在Spring Boot应用程序中访问URL时找不到页面

java - 具有嵌入式 jetty 的 Webapp 给出异常

android - I-Jetty 或 Jetty

javascript - 针对不同域之间实时聊天的技术堆栈建议