I’m having problems with the Channel API – any help would be greatly appreciated.
I’ve no problems with the API on the local dev server, but when I put it up on appspot, I get an esoteric exception thrown. Full stack trace is attached, but the headline is:
com.google.appengine.api.channel.ChannelFailureException: An unexpected error occurred.
Caused by: com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 2: Unknown
I’ve boiled the app down to a servlet and a jsp (both attached) to make sure I’m not doing anything over-complicated. Reading some of the messages on this forum and others it might be my misuse of tokens vs channel keys, but I’ve tried every combination I can think of to no avail!
Snippet of servlet:
ChannelService channelService = ChannelServiceFactory.getChannelService();
String channelKey = getChannelKey(userService.getCurrentUser().getUserId());
String token = channelService.createChannel(channelKey);
and
ChannelService channelService = ChannelServiceFactory.getChannelService();
channelService.sendMessage(new ChannelMessage(channelKey, message));
Snippet of jsp:
channel = new goog.appengine.Channel(channelToken);
socket = channel.open();
From the stack trace, the client is connecting to the channel OK, and successfully sends a message up, but the servlet writing the message back to the channel is the bit that fails.
Thanks very much in advance for any help!
Code:
Logs:
/ChannelTestMessage.do
com.google.appengine.api.channel.ChannelFailureException: An unexpected error occurred.
at com.google.appengine.api.channel.ChannelServiceImpl.getExceptionForError(ChannelServiceImpl.java:112)
at com.google.appengine.api.channel.ChannelServiceImpl.sendMessage(ChannelServiceImpl.java:68)
at com.webstersmalley.chessweb.web.ChannelTestController.sendMessage(ChannelTestController.java:74)
at com.webstersmalley.chessweb.web.ChannelTestController.getChannelTestMessage(ChannelTestController.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:43)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
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 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.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:439)
at com.google.net.rpc.impl.Server$RpcTask.runInContext(Server.java:573)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:448)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:688)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:326)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:318)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:446)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Caused by: com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 2: Unknown
at com.google.net.rpc.RpcStub$RpcCallbackDispatcher$1.runInContext(RpcStub.java:1050)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:448)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:688)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:326)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:318)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:446)
at com.google.net.rpc.RpcStub$RpcCallbackDispatcher.rpcFinished(RpcStub.java:1071)
at com.google.net.rpc.RPC.internalFinish(RPC.java:2184)
at com.google.net.rpc.impl.RpcNetChannel.finishRpc(RpcNetChannel.java:2338)
at com.google.net.rpc.impl.RpcNetChannel.messageReceived(RpcNetChannel.java:1267)
at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:328)
at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:299)
at com.google.net.async.Connection.handleReadEvent(Connection.java:474)
at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:831)
at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:103)
at com.google.net.async.GlobalEventRegistry$2.runLoop(GlobalEventRegistry.java:95)
at com.google.net.async.LoopingEventDispatcher$EventDispatcherThread.run(LoopingEventDispatcher.java:385)
I cross-posted this on Google’s own discussion forum for the Appengine Java API, and it was answered there.
A summary is that the problem occurs when high replication is switched on (as all new apps are, by default, now), and the non-default version is being used.
My app was a recent one (hence high rep was on), and I was trying a bunch of different ways of getting the Channels to work, so I was not using the default version of my app. Switching default to point at the latest version and using that URL caused the problem to go away!