In my Google App Engine Java application server application, I would like to enable Channel Presence servlets to track connections / disconnections to / from my channels using the channel API (as described here . I already edited the WEB-INF/appengine-web.xml as described.
Most servlets in my application use Sitebricks instead of classes that extend the HttpServlet to provide me with an easy way to create REST endpoints in my application. BUT, it seems that using Sitebricks in my class does not work, because I get WARNING: No file found for: /_ah/channel/connected/ when hitting the URL:
@At("/_ah/channel") @Service public class MyChannelPresenceServlet { ... @Post("/connected") public void connectedMethod() { ... } @Post("/disconnected") public void disconnectedMethod() { ... } ... }
Is it even possible to use Sitebricks to provide a REST endpoint for the presence of the channel for /-ah/channel/connected/ and /_ah/channel/disconnected/ ?
BONUS QUESTION
Let's say Sitebricks is not the way to go, and instead I need to stick with the regular servlet classes that extends HttpServlet and are configured through WEB-INF/web.xml . This other solution still does not work for me. Say I had to put this in my web.xml file:
<servlet> <servlet-name>channel_connect</servlet-name> <servlet-class>com.example.PresenceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>channel_connect</servlet-name> <url-pattern>/_ah/channel/connected/</url-pattern> </servlet-mapping>
In this example, com.example.PresenceServlet is a child of the HttpServlet and overrides the doPost method (HttpServletRequest, HttpServletResponse) from the parent. i still run into problems:
WARNING: /_ah/channel/connected/ java.lang.InstantiationException: com.ea.pogosocial.rest.ChannelServiceServlet at java.lang.Class.newInstance0(Class.java:357) at java.lang.Class.newInstance(Class.java:325) at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153) at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428) at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:66) at com.google.sitebricks.SitebricksFilter.doFilter(SitebricksFilter.java:88) at com.google.inject.servlet.FilterDefinition.doFilter(FilterDefinition.java:163) at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:58) at com.google.sitebricks.HiddenMethodFilter.doFilter(HiddenMethodFilter.java:75) at com.google.inject.servlet.FilterDefinition.doFilter(FilterDefinition.java:163) at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:58) at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:59) at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:49) at com.google.inject.servlet.FilterDefinition.doFilter(FilterDefinition.java:163) at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:58) at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118) at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.appstats.AppstatsFilter.doFilter(AppstatsFilter.java:141) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:110) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:380) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
All help is much appreciated. Especially from a Google employee.
(PS: I am using the GAE SDK 1.7.2. I look forward to 1.7.3)
Update
Another experiment passed. In the <servlet> for web.xml for my servlet class, I added this tag to make my servlet load at server startup (which, by the way, is done using mvn gae:run in my example). Now i get this output
WARNING: /_ah/channel/connected/: javax.servlet.UnavailableException: java.lang.InstantiationException: com.ea.pogosocial.rest.ChannelServiceServlet