1

我正在尝试在 Jetty 上运行使用 Camel Websocket 组件,但无法摆脱以下异常。我不确定这是与 Camel 一起运行的 Jetty 的问题,还是版本兼容性的问题,或者我的代码中缺少某些东西。

我已经把这个项目放在了 Github 上,以防有人想试一试。 https://github.com/soumyasd/jettycamelwebsocket

以下是运行应用程序的步骤。

  1. 在此类 src/main/java/demo/websocket/ 中更新您的 Twitter 凭据

  2. $mvn clean install

  3. $mvn jetty:run

  4. 将您的网络浏览器(我使用 Google Chrome)指向http://localhost:8080/index.html

java.lang.NullPointerException
    at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:236)[jetty-websocket-8.1.9.v20130131.jar:8.1.9.v20130131]
    at org.eclipse.jetty.websocket.WebSocketFactory.acceptWebSocket(WebSocketFactory.java:382)[jetty-websocket-8.1.9.v20130131.jar:8.1.9.v20130131]
    at org.eclipse.jetty.websocket.WebSocketServlet.service(WebSocketServlet.java:104)[jetty-websocket-7.6.8.v20121106.jar:7.6.8.v20121106]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)[javax.servlet-3.0.0.v201112011016.jar:]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:598)[jetty-servlet-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:486)[jetty-servlet-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:413)[jetty-servlet-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.Server.handle(Server.java:350)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:890)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:944)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630)[jetty-http-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230)[jetty-http-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)[jetty-server-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:606)[jetty-io-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)[jetty-io-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)[jetty-util-8.1.3.v20120416.jar:8.1.9.v20130131]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)[jetty-util-8.1.3.v20120416.jar:8.1.9.v20130131]
    at java.lang.Thread.run(Thread.java:680)[:1.6.0_45]

这是我的主要骆驼路线。

package demo.websocket; 

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.twitter.TwitterComponent;
import org.apache.camel.component.websocket.WebsocketComponent;

public class TwitterStreamRoute extends RouteBuilder{

        //put your twitter keys here to test 
        public final String CONSUMER_KEY = ""; 
        public final String CONSUMER_SECRET = ""; 
        public final String ACCESS_TOKEN = ""; 
        public final String ACCESS_TOKEN_SECRET = ""; 


        @Override
        public void configure() throws Exception {




        TwitterComponent tc = getContext().getComponent("twitter", TwitterComponent.class);
        tc.setAccessToken(ACCESS_TOKEN);
        tc.setAccessTokenSecret(ACCESS_TOKEN_SECRET);
        tc.setConsumerKey(CONSUMER_KEY);
        tc.setConsumerSecret(CONSUMER_SECRET);

        fromF("twitter://streaming/filter?type=polling&delay=%s&keywords=%s", "5", "pittsburgh")
                .process(new Processor() {
                                @Override
                                public void process(Exchange exchange) throws Exception {
                                        String res = exchange.getIn().getBody().toString();
                                        exchange.getOut().setBody(res);
                                }   
                        })  
        .to("websocket://0.0.0.0:9292/camel-tweet?sendToAll=true");
        }   

}

Camel 配置如下所示:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">


    <!-- Here we define Camel, notice the namespace it uses -->
    <camelContext xmlns="http://camel.apache.org/schema/spring" trace="true">
        <routeBuilder ref="twitter-route-id" ></routeBuilder>
    </camelContext>

    <bean id="twitter-route-id" class="demo.websocket.TwitterStreamRoute" />

</beans>

我的 web.xml 看起来像

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:camel="http://camel.apache.org/schema/spring"
        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
                        id="WebApp_ID" version="3.0">
                          <!-- your web.xml content here -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:camel-config.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>


  <display-name>Archetype Created Web Application</display-name>
                          </web-app>

~

我在我的 pom.xml 中使用以下版本。完整的 pom.xml 在这里

    <properties>
            <spring.version>3.2.2.RELEASE</spring.version>
            <camel.version>2.11.0</camel.version>
            <jetty.version>8.1.3.v20120416</jetty.version>
    </properties>

更新(2013 年 5 月 6 日,美国东部标准时间下午 3:04)

按照 Claus Ibsen 的建议,我更新了 pom.xml 以使用 Jetty 7.6.x 版本。但我仍然遇到同样的错误。同样在这种情况下,stackstrace 对于 WebSocketFactory 和 WebSocketServlet 具有相同的版本号。

java.lang.NullPointerException
    at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:236)[jetty-websocket-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.websocket.WebSocketFactory.acceptWebSocket(WebSocketFactory.java:382)[jetty-websocket-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.websocket.WebSocketServlet.service(WebSocketServlet.java:104)[jetty-websocket-7.6.8.v20121106.jar:7.6.8.v20121106]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)[javax.servlet-2.5.0.v201103041518.jar:]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:652)[jetty-servlet-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:447)[jetty-servlet-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1038)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:374)[jetty-servlet-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:972)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.Server.handle(Server.java:363)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:483)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:920)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:982)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:635)[jetty-http-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)[jetty-http-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[jetty-server-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)[jetty-io-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)[jetty-io-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[jetty-util-7.6.8.v20121106.jar:7.6.8.v20121106]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)[jetty-util-7.6.8.v20121106.jar:7.6.8.v20121106]
    at java.lang.Thread.run(Thread.java:662)[:1.6.0_32]

更新 2(美国东部标准时间 2013 年 5 月 6 日下午 4:06) 正如 @JoakimErdfelt 在评论中所建议的,带有请求响应信息的 Google Chrome 文件在这里

4

4 回答 4

3

我认为我没有弄清楚这个错误背后的确切原因。但是,我有一个无需对代码进行重大更改即可工作的解决方案。

我相信问题在于 Jetty 和 Jetty-maven-plugin 中 websocket 相关类的类加载。我的 pom.xml 中的插件配置不正确,或者我缺少一些条目。无论如何,在尝试了将近一天之后,我的替代解决方案如下:

我没有使用 Jetty-maven-plugin 来部署应用程序,而是使用 Jetty Runner ( http://wiki.eclipse.org/Jetty/Howto/Using_Jetty_Runner ) 来部署应用程序。注意:请在 pom.xml 中下载与您的 jetty.version 匹配的版本。

例如:

$java -jar jetty-runner-7.6.8.v20121106.jar target/jettycamelwebsocket.war

在此之后,我能够从我的 index.html 访问 websocket,没有任何问题。

现在,如果有人可以从 Jetty-maven-plugin 中解释为什么这不起作用(或缺少什么),那将非常有用。

这里有一些我觉得有用的参考资料。虽然它们已经过时了,但其中一些给了我一个提示,即 Jetty Maven 插件可能有问题,因此为我指明了正确的方向。

http://dev.eclipse.org/mhonarc/lists/jetty-users/msg00263.html

于 2013-05-07T03:37:35.830 回答
2

几天前我遇到了同样的例外。问题是空Connection对象。至少对我来说,根本原因是码头设置。确保在 jetty start.ini 文件中启用了 websocket。像这样的东西-

OPTIONS=Server,jsp,resources,ext,plus,websocket

它应该默认启用,但在我们的情况下它不是因为有人自定义了我们的 start.ini 并错误地删除了 websocket 支持。将其添加回 websocket 后,它与 Jetty 7.6.8 一起工作就像魅力一样。

于 2013-05-06T20:15:40.440 回答
1

WebSocketFactory:236上的 NPE是由于尝试升级而没有通过真正的 Jetty HTTP 连接到达。

最常见的原因:

  • 尝试在不是 jetty 的 Web 容器上使用 Jetty WebSockets。(如tomcat或jboss)
  • 尝试在不使用真正的 HTTP 连接(例如通过模拟库)的情况下对您的 websocket(servlet)进行单元测试
于 2013-05-06T16:22:08.467 回答
0

尝试使用 Jetty 7.6.x 作为我们测试并用于 Apache Camel 2.11 版本的版本。

于 2013-05-06T05:18:03.587 回答