I may have missed something about the actual problem, but imho, it comes from a bad use of the incoming message exchange. ServiceMix components take care about either: * reading the source only once so that such problem don't happen * in case where the source needs to be read multiple times, convert it to a re-readable source I don't think forcing a re-readable source (using a StringSource or whatever implementation) on the servicemix-http is a good thing. Actually, I think this would be a very bad idea, as you would not be able to support large requests concurrently. We may want to do that in servicemix-camel instead if there is a requirement, but I think the conversion of the source to a DOM source should solve most problems. Or should be change the default behavior for servicemix-camel and maybe add a property on the consumer to allow not transforming the content ?
On Thu, Sep 4, 2008 at 7:23 PM, quan tran <[EMAIL PROTECTED]> wrote: > 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. > > > > -- Cheers, Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/
