Hi,
I'm trying to get an ATOM feed working in my REST service. My approach
is to use the built in AtomFeedProvider by returning a Response with
the entity set as a Feed object:
@GET
@Path("/storage")
@ProduceMime( {"application/xml", "application/json", "text/html",
"application/atom+xml"} )
public Response myMethod(...){
....
Feed f = Abdera.getInstance().newFeed();
f.setTitle("title");
Locale loc = Locale.getDefault();
Entry e = f.addEntry();
e.addLink("http://localhost", "rel", "text/html",
item.getSubject(), loc.getDisplayLanguage(), 0L);
e.addAuthor("author");
e.addComment("comment");
e.addContributor("contributer");
builder.entity(f);
builder.type("application/atom+xml");
resp = builder.build();
return resp;
}
The problem I'm seeing is that by the time my response gets to the
provider the media type has changed to application/json. This makes is
output as JSON rather than XML:
public void writeTo(Feed feed, MediaType mt,
MultivaluedMap<String, Object> headers, OutputStream os)
throws IOException {
if (JSON_TYPE.equals(mt.toString())) {
Writer w = ATOM_ENGINE.getWriterFactory().getWriter("json");
feed.writeTo(w, os);
} else {
feed.writeTo(os);
}
}
That seems kind of weird to me. However I'm starting to think that it
is closely related to my secondary problem....when it does this line:
feed.writeTo(w, os);
I get an IOException:
14:33:27,433 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2)
ClientAbortException: java.net.SocketException: Connection reset by
peer: socket write error
14:33:27,433 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:366)
14:33:27,433 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:433)
14:33:27,433 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:398)
14:33:27,433 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:381)
14:33:27,449 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:88)
14:33:27,449 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:45)
14:33:27,449 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
sun.nio.cs.StreamEncoder$CharsetSE.writeBytes(StreamEncoder.java:336)
14:33:27,449 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
sun.nio.cs.StreamEncoder$CharsetSE.implFlushBuffer(StreamEncoder.java:404)
14:33:27,449 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
sun.nio.cs.StreamEncoder$CharsetSE.implFlush(StreamEncoder.java:408)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:152)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
java.io.OutputStreamWriter.flush(OutputStreamWriter.java:213)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONStream.writeQuoted(JSONStream.java:118)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONStream.writeField(JSONStream.java:150)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONStream.writeField(JSONStream.java:140)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONUtil.toJson(JSONUtil.java:268)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONUtil.writeList(JSONUtil.java:557)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONUtil.toJson(JSONUtil.java:243)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONUtil.writeList(JSONUtil.java:557)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONUtil.toJson(JSONUtil.java:321)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONUtil.toJson(JSONUtil.java:67)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONWriter.writeTo(JSONWriter.java:77)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.ext.json.JSONWriter.writeTo(JSONWriter.java:72)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.util.AbstractWriter.writeTo(AbstractWriter.java:78)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.abdera.parser.stax.FOMElement.writeTo(FOMElement.java:361)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.jaxrs.provider.AtomFeedProvider.writeTo(AtomFeedProvider.java:57)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.jaxrs.provider.AtomFeedProvider.writeTo(AtomFeedProvider.java:42)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:110)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:221)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:74)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:221)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:92)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:267)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:120)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:174)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.cxf.transport.servlet.AbstractCXFServlet.doGet(AbstractCXFServlet.java:156)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.valves.FastCommonAccessLogValve.invoke(FastCommonAccessLogValve.java:495)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
14:33:27,465 ERROR [STDERR](http-brad%2F10.1.11.27-8080-2) at
java.lang.Thread.run(Thread.java:595)
The request is also retried within the call (does tomcat auto retry
failed requests?) and succeeds with no stacktrace. I initially thought
the debug session was exceeding the http timeout but it does it when
not debugging.
Here's possibly the most confusing part, a copy of my stack at a point
along the response chain:
Daemon Thread [http-brad%2F10.1.11.27-8080-3] (Suspended)
AtomFeedProvider.writeTo(Feed, MediaType,
MultivaluedMap<String,Object>, OutputStream) line: 56
AtomFeedProvider.writeTo(Object, MediaType, MultivaluedMap,
OutputStream) line: 42
JAXRSOutInterceptor.handleMessage(Message) line: 110
PhaseInterceptorChain.doIntercept(Message) line: 221
OutgoingChainInterceptor.handleMessage(Message) line: 74
PhaseInterceptorChain.doIntercept(Message) line: 221
ChainInitiationObserver.onMessage(Message) line: 78
ServletDestination.invoke(ServletContext, HttpServletRequest,
HttpServletResponse) line: 92
ServletController.invokeDestination(HttpServletRequest,
HttpServletResponse, ServletDestination) line: 267
ServletController.invoke(HttpServletRequest, HttpServletResponse) line:
120
CXFServlet(AbstractCXFServlet).invoke(HttpServletRequest,
HttpServletResponse) line: 174
The only explanation I can think for those top two lines is that
JAXRSOutInterceptor is calling witeTo on the writer which in this case
is AtomFeedProvider. Could this be the cause of the IOException,
i.e.trying to write to a stream which has already been closed?
Here's the HTTP request & response from TCPMon:
GET
/otm-access-servlet/WORLD/TST/storage?authkey=XZ7Z6U6M6DWPM44Y5CF3ZNFRBWKA4S63XLFP2ZKJIVG55Y2QMUXA&fmt=feed
HTTP/1.1
Host: loire:8081
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9b4)
Gecko/2008030714 Firefox/3.0b4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.0.4.GA (build:
CVSTag=JBoss_4_0_4_GA date=200607171641)/Tomcat-5.5
Content-Type: application/atom+xml
Transfer-Encoding: chunked
Date: Thu, 19 Jun 2008 13:47:00 GMT
Notice that the content-type in the reponse is atom+xml which is what
I originally asked for although the document body (not shown) is JSON.
I've probably done something wrong somewhere but if anyone can see
something wrong here please feel free to remind me how stupid I am :-)
Thanks,
Brad