Reputation: 41
I have a class annotated by @ManagedService, it is not invoked. Servlet container is Jetty9.2.3.v20140905, atmosphere-runtime 2.3.1,AtomsphereServlet. The AtmosphereServlet is loaded successfully, browser side request can reach the AtmosphereServlet but the annotated class is not invoked. The warning is server side:
WARN org.atmosphere.websocket.DefaultWebSocketProcessor - No AtmosphereHandler or WebSocketHandler installed. Adding a default one.
here is configuration in 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>
Here is the code: breakpoint here is not invoked:
@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;
}
}
here is JS request:
var request = {
url: '/pusher/test?channel=/project/201',
contentType: 'application/json',
logLevel: 'debug',
transport: 'websocket',
trackMessageLength: true,
reconnectInterval: 5000,
enableXDR: true,
timeout: 60000
};
I use embedded jetty, Here is the function to 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();
}
Here is Atmosphere framework startup print log, it looks the annotated managedservice class has been scanned:
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 -
So far, tried the follows:
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 replace @ManagedService with AtmosphereHandler, get the same warning and my Handler is not invoked. It is complete same issue as managedservice annotation.
The strange is the client request doesn't invoke my annotated class, but websocket still connect successfully printed in browser console. It is also proved in wireshark, the websocket connect do established. It looks Atmosphere framework is using something default to deal with the request and establishing the websocket connection which i don't want to have,i want the request should be controlled in my annotated class, so that my class (in onready/on get) can check and decide to conn or not.
Here is the browser side console log:
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
Upvotes: 1
Views: 1057
Reputation: 41
Finally find the reason and solution.
root cause:
atmosphere-runtime.jar is not in WEB-INF/lib folder. If you don't have any problem to put it into WEB-INF/lib folder by adding dependency in your web app pom, just do it.
In my case,i got "slf4j java.lang.LinkageError loader constraint violation",because two pom modules (one of them is webapp module) both put atmosphere dependency in their pom file. Then Jetty classloader and default classloader both load atmosphere class.
Solution:
<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>
If you still want to leave atmosphere-runtime.jar in other folder than WEB-INF/lib, you can add the following to your web.xml, it do invoke my annotated class, but i am not sure its a good solution.
<init-param>
<param-name>org.atmosphere.cpr.AtmosphereHandler</param-name>
<param-value>com.teb.web.webpush.SubscribeRequest</param-value>
</init-param>
Upvotes: 2
Reputation: 1705
Are you using Jetty 9 embed interface by anay chance? Anyway just add in your web.xml
<init-param>
<param-name>org.atmosphere.cpr.packages</param-name>
<param-value>your package name</param-value>
</init-param>
And also make sure your class define a package :-)
Upvotes: 0