【问题标题】:Jetty websocket class loading issueJetty websocket类加载问题
【发布时间】:2015-11-18 21:54:44
【问题描述】:

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

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>

如果我使用嵌入式码头并以编程方式配置服务器并添加 Servlet,而不是使用独立码头,那么此示例运行良好。

但是,如果我将其打包为一场战争,然后将其部署在一个独立的码头实例中,我会得到以下观察结果:

  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 - stand alone WebSocket server

从上面的链接来看,这似乎是一个类加载问题,因为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)允许精细控制哪些类被视为系统类。

因此,为了能够做到这一点,我应该能够在 Jetty 初始化并将 WebSocket 类添加为系统类时获取 WebAppContext 的实例。

我试图寻找一个人如何能够实现相同但到目前为止没有运气?任何人都可以向我指出如何实现这一点的参考实现吗?


Java 版本:OpenJDK 7(最新)

码头:9.2.10.v20150310

操作系统:Ubuntu 14.04

提前致谢!

【问题讨论】:

    标签: websocket jetty


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      如果您已经按照link 设置了 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
      

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2015-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 2010-11-25
        • 1970-01-01
        • 2017-12-06
        • 1970-01-01
        相关资源
        最近更新 更多