All, I wonder if someone has some ideas on this. Any advices or document are appriciated. Thanks Quan
--- On Thu, 9/4/08, tpounds <[EMAIL PROTECTED]> wrote: > From: tpounds <[EMAIL PROTECTED]> > Subject: Re: RuntimeCamelException: java.io.IOException:Attempted read on > closed stream > To: [email protected] > Date: Thursday, September 4, 2008, 11:15 PM > Sandeep, > > This problem bit us not too long ago and I figured out why. > Since > ServiceMix makes use of of an InputStream (see: > http://cwiki.apache.org/SM/javaioioexception-stream-closed.html) > by mulitple > components, it requires that the InputStream being returned > can be read > multiple times if the message is being used (i.e. parsed > for logic, etc.) by > multiple components. This is the reason the wiki page says > to make use of > the StringSource so that a String buffer is stored in > memory to allow for > multiple reads of the response. The reason your input > stream cannot be read > multiple times is because the returned server objects is of > the type > http://commons.apache.org/io/api-release/org/apache/commons/io/input/AutoCloseInputStream.html > org.apache.commons.io.input.AutoCloseInputStream . > > from the AutoCloseInputStream Javadoc: > > > > Proxy stream that closes and discards the underlying > stream as soon as the > > end of input has been reached or when the stream is > explicitly closed. Not > > even a reference to the underlying stream is kept > after it has been > > closed, so any allocated in-memory buffers can be > freed even if the client > > application still keeps a reference to the proxy > stream. > > > > There are 2 reasons the AutoCloseInputStream is being used > to wrap the HTTP > server response: > > 1) The HTTP API being used is the Apache HTTP Commons > Client and it has > special rules to wrap the server responses in different > input streams > depending on the response headers. > > 2) The HTTP response coming from the Server is most likely > using the > http://en.wikipedia.org/wiki/Chunked_transfer_encoding > 'Transfer-Encoding: > chunked' header. Use a program like > http://www.wireshark.org Wireshark > or https://tcpmon.dev.java.net/ tcpmon to monitor the > response to see if > this is the case. I have a high degree of confidence that > it is. When the > server responds with a chunked encoding the HTTP Commons > client wraps the > response with a > http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/ChunkedInputStream.html > ChunkedInputStream enclosed in an AutoCloseInputStream > object. > > There are a few ways this can be fixed: > > 1) Change your server to respond using the normal > 'Content-Length: XXX' > header instead of 'Transfer-Encoding: chunked'. > This will cause the HTTP > commons client to return a different InputStream type which > can be read from > multiple times. > > 2) Modify the internal Camel/ServiceMix API's to use > the > http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/HttpMethodBase.html#getResponseBody() > HttpMethodBase.getResponseBody() instead of > http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/HttpMethodBase.html#getResponseBodyAsStream() > HttpMethodBase#getResponseBodyAsStream() . You will most > likely need to > wrap the HttpMethodBase.getResponseBody() call in a > http://java.sun.com/j2se/1.5.0/docs/api/java/io/ByteArrayInputStream.html > java.io.ByteArrayInputStream if you do not want to modify > the source code > too much. > > Example API replacement: > > > > replace HttpMethodBase.getResponseBodyAsStream() > > with new > ByteArrayInputStream(HttpMethodBase.getResponse()) > > > > I also found these threads and JIRA tickets which may be > related to the > server sending a chunked response. > Fuse JIRA http://open.iona.com/issues/browse/ESB-73 ESB-73 > > http://www.nabble.com/simple-http-soap-gateway-tp16543790p16543790.html > http://cwiki.apache.org/SM/discussion-forums.html#nabble-td5412079|a5709913 > > Hope this helps and good luck! > > Thanks, > Trevor > > > sandeep reddy wrote: > > > > Hi, > > I am still facing this same problem and I am not > able to resolve it. > > Please provide some advice on how to solve this or at > least a workaround. > > This is very important so please help us. > > > > Thanks, > > Sandeep > > > > > > sandeep reddy wrote: > >> > >>>Can you pinpoint the messages that are causing > this error? > >> > >> This is the response message from External > application: > >> when it is success: > >> <?xml version='1.0' > encoding='UTF-8'?> > >> > >> <response> > >> <message>password > changed</message> > >> <status>0</status> > >> </response> > >> when it is error: > >> <?xml version='1.0' > encoding='UTF-8'?><response><message>Internal > >> Server Error: failed to change > >> > password</message><status>1000</status></response> > >> > >>>Is there anything special to them? > >> > >> There is nothing special with response > message.And we are pretty sure > >> that message is not creating any sought of problem > because if message is > >> not proper it should fail for each time. And it > works fine having DEBUG > >> level in log4j.xml file. > >> > >>>BTW, I see you are using the Camel dead > >>>letter channel. Make sure you configure that > properly (not related to > >>>your current question, but the default > configuration just writes a > >>>message to the log when things go wrong without > information the JBI > >>>endpoint). > >> > >> Yes we are using Dead letter channel, and it > is configured > >> properly.This is camel configure method: > >> public void configure() { > >> > >> exception(java.lang.Throwable.class) > >> > .setBody(constant("<response><status>"+ > >> ErrorConstants.SYSTEM_ERROR > +"</status><message>System > >> Error</message></response>")) > >> > >> > .to("jbi:service:http://servicemix.in2m.com/operations/changepassword/ResponseGeneratorService?mep=in-out"); > >> > >> exception(java.net.SocketException.class) > >> > .setBody(constant("<response><status>"+ > >> ErrorConstants.SOCKET_ERROR > +"</status><message>Connection > >> Error</message></response>")) > >> > >> > .to("jbi:service:http://servicemix.in2m.com/operations/changepassword/ResponseGeneratorService?mep=in-out"); > >> > >> > >> > from("jbi:service:http://servicemix.in2m.com/operations/changepassword/RoutingService") > >> .convertBodyTo(DOMSource.class) //added > here > >> .choice() > >> > .when(header("userPrincipals").contains("director")) > > >> > >> > .to("jbi:service:http://servicemix.in2m.com/operations/changepassword/PortalService?mep=in-out") > >> .convertBodyTo(DOMSource.class) > //added here > >> > .when(header("userPrincipals").contains("portal")) > >> > >> > .to("jbi:service:http://servicemix.in2m.com/operations/changepassword/DirectorService?mep=in-out") > >> .convertBodyTo(DOMSource.class); > //added here > >> } > >> > > > > > > -- > View this message in context: > http://www.nabble.com/RuntimeCamelException%3A-java.io.IOException%3AAttempted-read-on-closed-stream-tp18869452p19314190.html > Sent from the ServiceMix - User mailing list archive at > Nabble.com.
