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/

Reply via email to