Jetty websocket类加载问题



我已经实现了一个基本的websocket服务器在Jetty(独立模式)。

MyWebSocketServlet.java

public class MyWebSocketServlet extends WebSocketServlet {
     @Override
     public void configure(WebSocketServletFactory webSocketServletFactory){
         webSocketServletFactory.getPolicy().setIdleTimeout(1000 * 10 * 60);
         webSocketServletFactory.setCreator(new MyWebSocketFactory());
     }
}

MyWebSocketFactory.java

public class MyWebSocketFactory implements WebSocketCreator {
    public Object createWebSocket(
        ServletUpgradeRequest servletUpgradeRequest
        , ServletUpgradeResponse servletUpgradeResponse) {
        return  new MyWebSocketListener();
    }
}

MyWebSocketListener.java

public class MyWebSocketListener implements WebSocketListener {
    private Session sessionInstance;
    public void onWebSocketBinary(byte[] bytes, int i, int i1) {
        ByteBuffer data = ByteBuffer.wrap(bytes, i, i1);
        try {
            sessionInstance.getRemote().sendBytes(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void onWebSocketClose(int i, String s) {
    }
    public void onWebSocketConnect(Session session) {
        sessionInstance = session;
    }
    public void onWebSocketError(Throwable throwable) {
        throwable.printStackTrace(System.err);
    }
    public void onWebSocketText(String s) {
        try {
            sessionInstance.getRemote().sendString(s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

web . xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app
   xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
   metadata-complete="false"
   version="3.1">
    <servlet>
        <servlet-name>WsEcho</servlet-name>
        <servlet-class>org.test.sanket.MyWebSocketServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>WsEcho</servlet-name>
        <url-pattern>/echo/*</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>HttpEcho</servlet-name>
        <servlet-class>org.test.sanket.MyHttpServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HttpEcho</servlet-name>
        <url-pattern>/httpecho/*</url-pattern>
    </servlet-mapping>
</web-app>
如果我使用嵌入式Jetty并以编程方式配置服务器并添加servlet,那么这个示例运行得很好,而不是使用独立Jetty。

但是,如果我打包相同的战争,然后在独立的jetty实例中部署相同的,我有以下观察:

  1. 我能够击中HttpServlet,即MyHttpServlet并接收响应
  2. 但是当我试图击中websocket servlet,即MyWebSocketServlet,我看到以下错误:

异常
java.lang.ClassCastException: org.eclipse.jetty.server.HttpConnection cannot be cast to org.eclipse.jetty.server.HttpConnection
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:175)
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:148)
at org.eclipse.jetty.websocket.servlet.WebSocketServlet.service(WebSocketServlet.java:151)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at     org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)

我确实看到了以下链接:Jetty -独立的WebSocket服务器

从上面的链接来看,这似乎是一个类加载问题,因为jetty websocket包被视为系统类包,如果已经被系统加载,则不应该被WebApp加载。

因此,根据上面的链接,我研究了建议的细节:http://www.eclipse.org/jetty/documentation/9.2.10.v20150310/jetty-classloading.html

在这个链接中,解决这个问题的方法之一是调用org.eclipse.jetty.webapp.WebAppContext。setSystemClasses(String Array)或org.eclipse.jetty.webapp.WebAppContext.addSystemClass(String)允许对哪些类被认为是系统类进行精细控制。

为了能够做到这一点,我应该能够获得WebAppContext的一个实例,当Jetty初始化和添加WebSocket类作为系统类。

我试着寻找一个人如何能够达到同样的效果,但到目前为止没有运气?有没有人能给我指出一个参考实现,如何实现这一点?


Java Version: OpenJDK 7(latest)

Jetty: 9.2.10.v20150310

操作系统:Ubuntu 14.04

提前感谢!

如果您已经按照这个链接设置了Jetty独立实例,那么您可能已经运行了以下命令:

[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging

如果是这样,那么当你尝试访问websocket servlet时,你会看到你注意到的异常。

你所需要做的就是,除了这个命令,你还需要初始化websocket模块,如下所示:

[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging,websocket

希望这对你有帮助!

不要在战争的WEB-INF/libWEB-INF/classes目录中包含org.eclipse.jetty.*

相关内容

  • 没有找到相关文章

最新更新