在Jetty上运行带有Camel组件的简单websocket的异常

时间:2013-05-05 18:31:30

标签: websocket jetty apache-camel

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

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

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

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

  2. $mvn clean install

  3. $mvn jetty:run

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

  5. 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是here

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

    我更新了pom.xml以使用Claus Ibsen建议的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文件为here

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

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

默认情况下应启用它,但它不是我们的情况,因为有人定制了我们的start.ini并错误地删除了websocket支持。添加后,websocket的工作效果与Jetty 7.6.8相似。

答案 2 :(得分:1)

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

最常见的原因:

  • 尝试在不是jetty的Web容器上使用Jetty WebSockets。 (如tomcat或jboss)
  • 试图在不使用真正的HTTP连接(例如通过模拟库)的情况下对websocket(servlet)进行单元测试

答案 3 :(得分:0)

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