>我正在尝试在自执行战争中运行Cometd websocket服务器,该战争以嵌入式模式运行码头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 插件构建一个包含码头服务器 8.1.12 的 uber jar,另一个包含第一个 jar 作为战争覆盖。覆盖层将所有码头服务器类放在战争的根目录中,因此可以使用"java -jar my.war"运行。因为 Cometd 也需要 websockets 的码头,所以我双倍确保 WEB-INF/lib dir 中的所有依赖项和 jar 也都是 8.1.12。因此,整个服务器只有一台服务器及其码头8.1.12。所有其他帖子/问题都是因为非码头或非 websocket 容器或非 http 连接,但这是 100% 码头 8.1.12,当与独立的外部码头 8.1.12 实例一起部署时,Web 应用程序工作正常。
来自 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
以下是运行嵌入式码头的代码:
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
这个问题感觉可能与 HttpConnection 等 jetty 类之间的类加载问题有关(我读了一篇关于 HttpConnection-ThreadLocal 和 osgi 的文章),这些类在 webapp 和封闭的 jetty 服务器之间共享。这些类实际上在两个地方都有,但我找不到将它们分开的方法,因为两个地方都需要它们。
也许有一种方法可以让 jetty 与 webapp 类加载器共享其类加载类?在这一点上,我已经没有想法了,不知道接下来可以尝试什么。我能做些什么来让它工作?
让它工作了。在比较了有效的外部码头服务器与嵌入式配置之间的确切差异后,我能够使其工作。这需要一点试验和错误,而且并不完全明显,所以我分享我为别人所做的。
首先,我在 WEB-INF/lib 中唯一需要的码头罐是这个:
jetty-util-8.1.12.v20130726.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,这是进度。因此,通过查看另一个工作码头服务器的日志行,并阅读一些非阻塞连接器,我使用了这个连接器而不是 SocketConector:
import org.eclipse.jetty.server.nio.SelectChannelConnector;
. . .
SelectChannelConnector connector = new SelectChannelConnector();
这两个非常简单的更改让我启动并运行。
我遇到了同样的问题,我试图构建的应用程序依赖于atmosphere
我在Jetty-9
下运行该应用程序。
我发现war/WEB-INF/lib
中的码头罐是:
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
问题消失了。
我在将雄猫与 vaadin 7 和大气一起使用时遇到此错误。该错误对应用程序的良好行为没有影响,但时不时地弹出。
java.lang.NullPointerException
at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:238)
通过从我的类路径中删除 gwt-dev-2.7.0.vaadin4.jar 解决了这个问题。看来反正我也不需要它。