Ticket #290 (closed defect: fixed)
"Stream closed" error with JAX RS resources on Tomcat
| Reported by: | sdm | Owned by: | mpo |
|---|---|---|---|
| Priority: | major | Milestone: | 0.4 |
| Component: | < Misc | Version: | trunk |
| Keywords: | tomcat, restlet | Cc: |
Description
A Kauri application which uses JAX RS crashes sometimes when deployed on Tomcat. The problem occurs when posting JSON data: sometimes, not always, the JSON data received by the JAX RS resource method is empty.
This was tested on Tomcat 5.5, but when testing on Tomcat 6, the following error occurred, which is probably the reason for the JSON data not arriving:
org.restlet.ext.jaxrs.internal.exceptions.ConvertRepresentationException: Could not convert the message body to a java.lang.String
at org.restlet.ext.jaxrs.internal.exceptions.ConvertRepresentationException.object(ConvertRepresentationException.java:55)
at org.restlet.ext.jaxrs.internal.wrappers.params.EntityGetter.getValue(EntityGetter.java:112)
at org.restlet.ext.jaxrs.internal.wrappers.params.ParameterList.get(ParameterList.java:1069)
at org.restlet.ext.jaxrs.internal.wrappers.AbstractMethodWrapper.internalInvoke(AbstractMethodWrapper.java:166)
at org.restlet.ext.jaxrs.internal.wrappers.ResourceMethod.invoke(ResourceMethod.java:291)
at org.restlet.ext.jaxrs.JaxRsRestlet.invokeMethod(JaxRsRestlet.java:654)
at org.restlet.ext.jaxrs.JaxRsRestlet.handle(JaxRsRestlet.java:398)
at org.kauriproject.routing.impl.components.KauriJaxRsRestlet.handle(KauriJaxRsRestlet.java:143)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.kauriproject.routing.impl.components.SequenceRouter.handle(SequenceRouter.java:74)
at org.kauriproject.routing.impl.routing.KauriRouter.handle(KauriRouter.java:62)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.kauriproject.security.infrastructure.SecurityFilter.doHandle(SecurityFilter.java:155)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.kauriproject.representation.build.impl.RepresentationFilterFactory$RepresentationFilter.doHandle(RepresentationFilterFactory.java:71)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.kauriproject.runtime.module.restservice.WrapperRestlet.handle(WrapperRestlet.java:41)
at org.kauriproject.runtime.module.restservice.RestserviceShield.handle(RestserviceShield.java:47)
at org.kauriproject.runtime.module.restservice.RestserviceFacet$RestserviceRouter.handle(RestserviceFacet.java:104)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:153)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.engine.ChainHelper.handle(ChainHelper.java:111)
at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:71)
at org.restlet.Application.handle(Application.java:397)
at org.kauriproject.runtime.module.restservice.RestserviceFacet$IntraApplicationRestserviceProxy.handle(RestserviceFacet.java:117)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Router.handle(Router.java:504)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Router.handle(Router.java:504)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:153)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.engine.ChainHelper.handle(ChainHelper.java:111)
at org.restlet.Component.handle(Component.java:399)
at org.kauriproject.runtime.module.restservice.RestserviceManager$KauriComponent.superHandle(RestserviceManager.java:80)
at org.kauriproject.runtime.module.restservice.RestserviceManager$KauriComponent$1.handle(RestserviceManager.java:64)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.kauriproject.i18n.locale_assignment.LocaleAssignmentFilter.doHandle(LocaleAssignmentFilter.java:88)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.kauriproject.i18n.impl.I18nFilterFactory$I18nFilter.doHandle(I18nFilterFactory.java:42)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.restlet.routing.Filter.doHandle(Filter.java:156)
at org.restlet.routing.Filter.handle(Filter.java:201)
at org.kauriproject.runtime.module.restservice.RestserviceManager$KauriComponent.handle(RestserviceManager.java:73)
at org.restlet.ext.servlet.ServletAdapter.service(ServletAdapter.java:201)
at org.kauriproject.runtime.servlet.KauriServlet.service(KauriServlet.java:143)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.readByte(InputBuffer.java:315)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:105)
at org.restlet.ext.jaxrs.internal.util.Util.copyToStringBuilder(Util.java:359)
at org.restlet.ext.jaxrs.internal.provider.StringProvider.readFrom(StringProvider.java:143)
at org.restlet.ext.jaxrs.internal.provider.StringProvider.readFrom(StringProvider.java:61)
at org.restlet.ext.jaxrs.internal.wrappers.provider.SingletonProvider.readFrom(SingletonProvider.java:307)
at org.restlet.ext.jaxrs.internal.wrappers.params.EntityGetter.getValue(EntityGetter.java:106)
... 73 more
After googling this error, we found out that this problem is caused by the Restlet version. Apparently, this problem is solved in Restlet 2.0-M5:
Fixed integration issue with Tomcat due to the GC releasing
Restlet representations, indirectly closing the underlying
Tomcat buffer which could have been reused for another
request, causing unexpected socket reading issues.
Initially reported by Denys Hryvastov.
To try out if this was indeed the case, I downloaded Kauri and updated it to use one of the latest Restlet versions, 2.0-M7. Because of quite some changes in the new Restlet API, I didn't manage to build Kauri entirely correctly. I checked the Restlet changelog http://www.restlet.org/documentation/2.0/jse/changes to find out what had changed, but I couldn't solve all the compilation errors.
To make it somewhat easier to test if the fix in 2.0-M5 solved the problem, I tried something else. Currently, Kauri uses Restlet version svn 5141, so we decided to include the fix in this version and build Restlet locally with the bug fix. The changes were made in the Restlet svn commit 5355: http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4374&dsMessageId=2399301
After some testing on Tomcat, the error didn't occur anymore, so the problem was indeed solved by using a more recent Restlet version.
Change History
comment:2 in reply to: ↑ 1 Changed 3 years ago by jgou
- Keywords tomcat, restlet added; tomcat removed
- Component changed from -- unknown -- to < Misc
Replying to mpo:
The action to take sounds like "upgrade to newest restlet 2.0-x"
As you point out this isn't just a trivial task, so I'ld like to open the discussion if we take this in with 0.4 or postpone until 0.5
The question is indeed not "if" we should upgrade, but "when". In terms of priority, this is atm not critical for end users considering the amount of unresolved issues for 0.4 .
(By the way: There are some other jax-rs related issues here that are equally likely solved by doing the upgrade)
I haven't seen much changes on the jax-rs extension the last year, but at the very least upgrading to the newest restlet would make our issues easier to debug or report to restlet.
For now I suggest keeping the upgrade on board for 0.4 (since there is not really set a due date yet).
The action to take sounds like "upgrade to newest restlet 2.0-x"
As you point out this isn't just a trivial task, so I'ld like to open the discussion if we take this in with 0.4 or postpone until 0.5
(By the way: There are some other jax-rs related issues here that are equally likely solved by doing the upgrade)