氛围@managedservice类未在jetty 9

时间:2015-05-15 15:07:35

标签: atmosphere

我有一个由@ManagedService注释的类,它没有被调用。 Servlet容器是Jetty9.2.3.v20140905,大气运行时2.3.1,AtomsphereServlet。 AtmosphereServlet已成功加载,浏览器端请求可以到达AtmosphereServlet,但不会调用带注释的类。 警告是服务器端:

WARN  org.atmosphere.websocket.DefaultWebSocketProcessor - No AtmosphereHandler or WebSocketHandler installed. Adding a default one.

这是Jetty web.xml中的配置

<servlet>
    <description>AtmosphereServlet</description>
    <servlet-name>AtmosphereServlet</servlet-name>
    <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
    <!-- List of init-param -->
    <init-param>
        <param-name>org.atmosphere.cpr.broadcaster.shareableThreadPool</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>org.atmosphere.cpr.broadcaster.maxProcessingThreads</param-name>
        <param-value>10</param-value>
    </init-param>
    <init-param>
        <param-name>org.atmosphere.cpr.broadcaster.maxAsyncWriteThreads</param-name>
        <param-value>10</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <!-- If you want to use Servlet 3.0 -->
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>AtmosphereServlet</servlet-name>
    <!-- Any mapping -->
    <url-pattern>/pusher/*</url-pattern>
</servlet-mapping>

以下是代码:此处不使用断点:

@ManagedService(path = "/test")

public class SubscribeRequest {
    private Logger log = Logger.getLogger(this.getClass().getName());

    @Get
    public void onGet(AtmosphereResource r) {
        String channel=r.getRequest().getParameter("channel");
        if(channel == null) {
            return;
        }
        if(channel.startsWith("/project/")) {
            BroadcasterFactory f = r.getAtmosphereConfig().getBroadcasterFactory();           
            f.lookup(channel, true).addAtmosphereResource(r);
            log.log(Level.INFO, "Subscribe for " + channel + "\n");
            r.suspend();
        }else{
            //not support other channel yet
            log.log(Level.INFO, "Subscribe for NOT-SUPPORT channel:" + channel + "\n");
        }
    }

    @Message
    public String onMessage(AtmosphereResource r, String message) throws IOException {
        log.log(Level.INFO,message);
        return message;
    }

}

这里是JS请求:

var request = {
    url: '/pusher/test?channel=/project/201',
    contentType: 'application/json',
    logLevel: 'debug',
    transport: 'websocket',
    trackMessageLength: true,
    reconnectInterval: 5000,
    enableXDR: true,
    timeout: 60000
  };

我使用嵌入式jetty,这是startjetty的功能:

private void startJetty(String workingDir, String baseDir, String configDir, String contextPath, String warFile) throws Exception {
     Server server = new Server();
     .....
    WebAppContext webapp = new WebAppContext();
    webapp.setContextPath(contextPath);
    if(runInsideIntelliJ) { // Allows running/debugging from within e.g. IntelliJ
      log.fine("Running project from inside IDE environment. Running directly from source web files.");
      webapp.setWar(workingDir+"/web/src/main/webapp/");
      String extraClasspath = workingDir + "/web/target/classes/";
      extraClasspath += ";" + new String(Files.readAllBytes(Paths.get(workingDir + "/web/web.debug.classpath")));
      webapp.setExtraClasspath(extraClasspath);
      webapp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");

      webapp.addFilter("com.teb.web.CorsDebugFilter", "/protected/rest/*", EnumSet.allOf(DispatcherType.class));
    } else {
      webapp.setWar(warFile);
    }
    ServletHolder defaultServlet = new ServletHolder(DefaultServlet.class);
    defaultServlet.setInitParameter("cacheControl", "max-age=0,public");
    defaultServlet.setName("default");
    webapp.addServlet(defaultServlet, "/");

    org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
    classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");

    webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
            ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");

    HandlerCollection handlers = new HandlerCollection();
    RequestLogHandler requestLogHandler = new RequestLogHandler();
    handlers.setHandlers(new Handler[]{webapp, /*rootContextHandler,*/ requestLogHandler});
    server.setHandler(handlers);

    ...
    // Start the server
    server.start();
    server.join();
  }

这是Atmosphere框架启动打印日志,它看起来已经扫描了带注释的托管服务类:

2015-05-16 00:04:33,954 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using org.atmosphere.cpr.DefaultAnnotationProcessor for processing annotation
2015-05-16 00:04:33,955 [main] INFO  org.atmosphere.cpr.DefaultAnnotationProcessor - AnnotationProcessor class org.atmosphere.cpr.DefaultAnnotationProcessor$ServletContainerInitializerAnnotationProcessor being used
2015-05-16 00:04:33,956 [main] WARN  org.atmosphere.cpr.DefaultAnnotationProcessor - Unable to detect annotations. Application may fail to deploy.
2015-05-16 00:04:33,957 [main] INFO  org.atmosphere.cpr.AnnotationHandler - Found Annotation in class com.teb.ea.web.webpush.SubscribeRequest being scanned: interface org.atmosphere.config.service.ManagedService
2015-05-16 00:04:33,959 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Auto detecting atmosphere handlers /WEB-INF/classes/
2015-05-16 00:04:33,960 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Auto detecting WebSocketHandler in /WEB-INF/classes/
2015-05-16 00:04:33,963 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed WebSocketProtocol org.atmosphere.websocket.protocol.SimpleHttpProtocol 
2015-05-16 00:04:34,003 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installing Default AtmosphereInterceptors
2015-05-16 00:04:34,004 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.CorsInterceptor : CORS Interceptor Support
2015-05-16 00:04:34,005 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.CacheHeadersInterceptor : Default Response's Headers Interceptor
2015-05-16 00:04:34,006 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.PaddingAtmosphereInterceptor : Browser Padding Interceptor Support
2015-05-16 00:04:34,007 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.AndroidAtmosphereInterceptor : Android Interceptor Support
2015-05-16 00:04:34,009 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.HeartbeatInterceptor : Heartbeat Interceptor Support
2015-05-16 00:04:34,010 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.SSEAtmosphereInterceptor : SSE Interceptor Support
2015-05-16 00:04:34,011 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.JSONPAtmosphereInterceptor : JSONP Interceptor Support
2015-05-16 00:04:34,012 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.JavaScriptProtocol : Atmosphere JavaScript Protocol
2015-05-16 00:04:34,012 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor : org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor
2015-05-16 00:04:34,013 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.OnDisconnectInterceptor : Browser disconnection detection
2015-05-16 00:04:34,013 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   org.atmosphere.interceptor.IdleResourceInterceptor : org.atmosphere.interceptor.IdleResourceInterceptor
2015-05-16 00:04:34,013 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults to disable them.
2015-05-16 00:04:34,014 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor CORS Interceptor Support with priority FIRST_BEFORE_DEFAULT 
2015-05-16 00:04:34,015 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Default Response's Headers Interceptor with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Browser Padding Interceptor Support with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Android Interceptor Support with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.interceptor.HeartbeatInterceptor - HeartbeatInterceptor configured with padding value 'X', client frequency 60 seconds and server frequency 0 seconds
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Heartbeat Interceptor Support with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor SSE Interceptor Support with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor JSONP Interceptor Support with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Atmosphere JavaScript Protocol with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Browser disconnection detection with priority AFTER_DEFAULT 
2015-05-16 00:04:34,016 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor org.atmosphere.interceptor.IdleResourceInterceptor with priority BEFORE_DEFAULT 
2015-05-16 00:04:34,017 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Using EndpointMapper class org.atmosphere.util.DefaultEndpointMapper
2015-05-16 00:04:34,017 [main] WARN  org.atmosphere.cpr.AtmosphereFramework - No BroadcasterCache configured. Broadcasted message between client reconnection will be LOST. It is recommended to configure the org.atmosphere.cache.UUIDBroadcasterCache
2015-05-16 00:04:34,017 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Default Broadcaster Class: org.atmosphere.cpr.DefaultBroadcaster
2015-05-16 00:04:34,017 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Broadcaster Shared List Resources: false
2015-05-16 00:04:34,017 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Broadcaster Polling Wait Time 100
2015-05-16 00:04:34,017 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Shared ExecutorService supported: true
2015-05-16 00:04:34,018 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Messaging Thread Pool Size: 10
2015-05-16 00:04:34,018 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Async I/O Thread Pool Size: 10
2015-05-16 00:04:34,018 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Using BroadcasterFactory: org.atmosphere.cpr.DefaultBroadcasterFactory
2015-05-16 00:04:34,018 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Using AtmosphereResurceFactory: org.atmosphere.cpr.DefaultAtmosphereResourceFactory
2015-05-16 00:04:34,018 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Using WebSocketProcessor: org.atmosphere.websocket.DefaultWebSocketProcessor
2015-05-16 00:04:34,018 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Invoke AtmosphereInterceptor on WebSocket message true
2015-05-16 00:04:34,019 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - HttpSession supported: false
2015-05-16 00:04:34,019 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using org.atmosphere.inject.InjectableObjectFactory for dependency injection and object creation
2015-05-16 00:04:34,019 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using async support: org.atmosphere.container.Jetty9AsyncSupportWithWebSocket running under container: jetty/9.2.3.v20140905 with WebSocket enabled.
2015-05-16 00:04:34,020 [main] INFO  org.atmosphere.cpr.AtmosphereFramework - Atmosphere Framework 2.3.1 started.
2015-05-16 00:04:34,020 [main] INFO  org.atmosphere.cpr.AtmosphereFramework -   

到目前为止,尝试了以下内容:

1 add the follow init-param

    <init-param>
        <param-name>org.atmosphere.cpr.packages</param-name>
        <param-value>com.mobilaris.ea.web.webpush</param-value>
    </init-param>

2 set annotated class path same as servlet mapping in web.xml, it is /pusher/test

3用AtmosphereHandler替换@ManagedService,得到 同样的警告和我的处理程序没有被调用。它与managedservice注释完全相同。

奇怪的是客户端请求没有调用我的带注释的类,但websocket仍然连接成功打印在浏览器控制台中。在wireshark中也证明了,websocket连接确实建立了。看起来Atmosphere框架正在使用默认的东西来处理请求并建立我不想拥有的websocket连接,我希望请求应该在我的注释类中进行控制,以便我的类(在onready / on上) get)可以检查并决定是否conn。

这是浏览器端控制台日志:

atmosphere.js:3221 Invoking executeWebSocket
atmosphere.js:3221 Using URL: ws://localhost:9999/pusher/test?channel=201&X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.2.11-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&Content-Type=application/json&X-atmo-protocol=true
...
atmosphere.js:3221 Sat May 16 2015 08:03:50 GMT+0200 (CEST) Atmosphere: websocket.onopen
atmosphere.js:3221 Websocket successfully opened
...
atmosphere.js:3221 Sat May 16 2015 08:04:50 GMT+0200 (CEST) Atmosphere: Firing closedByClient
angular-1.3.14.js:11607 ReferenceError: author is not defined
    at Object.request.onClientTimeout (http://localhost:9999/authedfolder/js/my.js:41:57)
    at http://spyboost.github.io/angular-atmosphere/service/angular-atmosphere-service.js:16:30
    at Scope.$get.Scope.$eval (http://localhost:9999/authedfolder/components/angularjs/angular-1.3.14.js:14401:28)
    at Scope.$get.Scope.$apply (http://localhost:9999/authedfolder/components/angularjs/angular-1.3.14.js:14500:23)
    at Object.subscribe.angular.forEach.result.(anonymous function) [as onClientTimeout] (http://spyboost.github.io/angular-atmosphere/service/angular-atmosphere-service.js:15:28)
    at _f (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:2767:31)
    at _invokeFunction (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:2721:17)
    at _invokeCallback (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:2850:21)
    at _onClientTimeout (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:1636:17)
    at http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:1623:25(anonymous function) @ angular-1.3.14.js:11607$get @ angular-1.3.14.js:8557$get.Scope.$apply @ angular-1.3.14.js:14502subscribe.angular.forEach.result.(anonymous function) @ angular-atmosphere-service.js:15_f @ atmosphere.js:2767_invokeFunction @ atmosphere.js:2721_invokeCallback @ atmosphere.js:2850_onClientTimeout @ atmosphere.js:1636(anonymous function) @ atmosphere.js:1623
atmosphere.js:3221 Sat May 16 2015 08:04:50 GMT+0200 (CEST) Atmosphere: Firing closedByClient
atmosphere.js:3221 Sat May 16 2015 08:04:50 GMT+0200 (CEST) Atmosphere: websocket.onclose
atmosphere.js:3221 Websocket closed, reason: Unknown: no status code was provided even though one was expected.
atmosphere.js:3221 Websocket closed, wasClean: true

2 个答案:

答案 0 :(得分:2)

最后找到原因和解决方案。

根本原因:

atmosphere-runtime.jar不在WEB-INF / lib文件夹中。 如果通过在web应用程序pom中添加依赖项将它放入WEB-INF / lib文件夹没有任何问题,那就去做吧。

在我的情况下,我得到了“slf4j java.lang.LinkageError加载器约束违规”,因为两个pom模块(其中一个是webapp模块)都将氛围依赖放在他们的pom文件中。然后Jetty类加载器和默认的类加载器都加载了氛围类。

解决方案:

  1. 只将依赖项放在一个pom中,如果需要更改代码,则必须这样做。
  2. 将排除添加到大气依赖:
  3.   <dependency>
          <groupId>org.atmosphere</groupId>
          <artifactId>atmosphere-runtime</artifactId>
          <exclusions>
              <exclusion>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-log4j12</artifactId>
              </exclusion>
              <exclusion>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-api</artifactId>
              </exclusion>
              <exclusion>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
              </exclusion>
          </exclusions>
      </dependency>

    如果您仍想将amb-runtime.jar保留在除WEB-INF / lib之外的其他文件夹中,您可以将以下内容添加到您的web.xml中,它会调用我的带注释的类,但我不确定它是否合适溶液

    <init-param>
        <param-name>org.atmosphere.cpr.AtmosphereHandler</param-name>
        <param-value>com.teb.web.webpush.SubscribeRequest</param-value>
    </init-param>
    

答案 1 :(得分:0)

您是否正在使用Jetty 9嵌入式界面?无论如何只需添加你的web.xml

    <init-param>
        <param-name>org.atmosphere.cpr.packages</param-name>
        <param-value>your package name</param-value>
    </init-param>

并确保您的班级定义一个包: - )