Hi, I'm hoping maybe this problem looks familiar to somebody out there.. I'm using Restlet 2.1.4 on GAE, and I'm seeing intermittent NPEs with the (partial) stack trace below. This is happening on about 1% of requests.
17:00:19.465 org.restlet.engine.io.BioUtils getReader: The GAE edition is unable to return a reader for a writer representation. E 17:00:19.465 org.restlet.engine.adapter.ServerAdapter commit: An exception occured writing the response entity java.lang.NullPointerException at java.io.Reader.<init>(Reader.java:78) at java.io.BufferedReader.<init>(BufferedReader.java:94) at org.restlet.engine.io.ReaderInputStream.<init>(ReaderInputStream.java:101) at org.restlet.engine.io.BioUtils.getStream(BioUtils.java:354) at org.restlet.representation.CharacterRepresentation.getStream(CharacterRepresentation.java:70) at org.restlet.util.WrapperRepresentation.getStream(WrapperRepresentation.java:151) at org.restlet.engine.application.RangeRepresentation.getStream(RangeRepresentation.java:117) at org.restlet.engine.application.RangeRepresentation.write(RangeRepresentation.java:146) at org.restlet.engine.adapter.ServerCall.writeResponseBody(ServerCall.java:510) at org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:454) In the full stack trace further below, I've interspersed the source code at each stack level. Here's my analysis so far: The Reader constructor has received a null "lock" parameter from its caller. BufferedReader is just passing its first argument ("in", a Reader) to super, so "in" must be null. which means that in ReaderInputStream's constructor, "reader" is null which means that in BioUtils.getStream, "reader" (its first arg) is null which means that in CharacterRepresentation.getStream, getReader() is returning null CharacterRepresentation is abstract and doesn't implement getReader, so its implementation is coming from one of its subclasses. Since it is getting called from WrapperRepresentation.getStream, that indicates that the CharacterRepresentation is a wrapped representation. Since that is getting called from RangeRepresentation.getStream, we know that the wrapper is a RangeRepresentation, although we don't know what the wrapped representation is (other than it is derived from CharacterRepresentation) Since that is getting called from ServerCall.writeResponseBody, for the object "entity", we know that "entity" is a RangeRepresentation. The problem is that I'm expecting "entity" to be a JacksonRepresentation, not a RangeRepresentation. And I can't find any code that instantiates a RangeRepresention outside of RangeFilter, which I'm not using (to my knowledge). Any ideas? -Andy W 17:00:19.465 org.restlet.engine.io.BioUtils getReader: The GAE edition is unable to return a reader for a writer representation. E 17:00:19.465 org.restlet.engine.adapter.ServerAdapter commit: An exception occured writing the response entity java.lang.NullPointerException at java.io.Reader.<init>(Reader.java:78) protected Reader(Object lock) { if (lock == null) { throw new NullPointerException(); at java.io.BufferedReader.<init>(BufferedReader.java:94) super(in); at org.restlet.engine.io.ReaderInputStream.<init>(ReaderInputStream.java:101) reader = (reader instanceof BufferedReader) ? (BufferedReader) reader : new BufferedReader(reader, IoUtils.BUFFER_SIZE); at org.restlet.engine.io.BioUtils.getStream(BioUtils.java:354) result = new ReaderInputStream(reader, characterSet); at org.restlet.representation.CharacterRepresentation.getStream(CharacterRepresentation.java:70) return BioUtils.getStream(getReader(), getCharacterSet()); at org.restlet.util.WrapperRepresentation.getStream(WrapperRepresentation.java:151) return getWrappedRepresentation().getStream(); at org.restlet.engine.application.RangeRepresentation.getStream(RangeRepresentation.java:117) return new RangeInputStream(super.getStream(), getSize(), getRange()); at org.restlet.engine.application.RangeRepresentation.write(RangeRepresentation.java:146) BioUtils.copy(getStream(), outputStream); at org.restlet.engine.adapter.ServerCall.writeResponseBody(ServerCall.java:510) entity.write(responseEntityStream); at org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:454) at org.restlet.ext.servlet.internal.ServletCall.sendResponse(ServletCall.java:459) at org.restlet.engine.adapter.ServerAdapter.commit(ServerAdapter.java:196) at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:153) at org.restlet.ext.servlet.ServerServlet.service(ServerServlet.java:1089) 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 com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:59) at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:49) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60) 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 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.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266) 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 com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446) at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437) at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444) at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:188) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300) at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441) at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251) at java.lang.Thread.run(Thread.java:724) ------------------------------------------------------ http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3077086