You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@servicemix.apache.org by sandeep reddy <sa...@in2m.com> on 2008/08/07 14:36:47 UTC

RuntimeCamelException: java.io.IOException:Attempted read on closed stream


Hi Servicemix-guys, 

Following is the my use case message flow:

            Client App <--> HTTPConsumerSu --> CamelSu <---> HTTPProviderSu
<--> External App

We are struggling with a problem having INFO level in log4j.xml for
org.apache.servicemix logger and WARN levels for rest of all loggers.
Problem was java.io.IOException: Stream closed. The message was not
delivered to External App. Following is the link for forum discussion :

    http://cwiki.apache.org/SM/discussion-forums.html#nabble-td18688010
    
The error is related to
http://cwiki.apache.org/SM/javaioioexception-stream-closed.html and is
occurring for us in ServiceMix-Camel component.

It finally got resolved based on suggestion mentioned in the forum.

But this time I am facing error after getting response from External
application. The error log is:

    com.ctc.wstx.exc.WstxIOException: Attempted read on closed stream.
    at
com.ctc.wstx.stax.WstxInputFactory.doCreateSR(WstxInputFactory.java:548)
    at
com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:604)
    at
com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:660)
    at
com.ctc.wstx.stax.WstxInputFactory.createXMLStreamReader(WstxInputFactory.java:331)
    at
org.apache.servicemix.jbi.jaxp.StAXSourceTransformer.toXMLStreamReader(StAXSourceTransformer.java:86)
    at
org.apache.servicemix.http.endpoints.DefaultHttpConsumerMarshaler.sendOut(DefaultHttpConsumerMarshaler.java:78)
    at
org.apache.servicemix.http.endpoints.HttpConsumerEndpoint.sendOut(HttpConsumerEndpoint.java:392)
    at
org.apache.servicemix.http.endpoints.HttpConsumerEndpoint.process(HttpConsumerEndpoint.java:273)
    at
org.apache.servicemix.http.HttpBridgeServlet.doPost(HttpBridgeServlet.java:71)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)

To solve the above problem I tried same way as Gert suggested having
convertToBody(DOMSource.class) after to(.......) statement. 
Camel configuration with the added changes is as follows :

    
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

After the above changes almost all working, but some times I am getting
following exception:

ERROR - DeadLetterChannel              - Failed delivery forexchangeId:
ID-rsandeep/34384-1218012001777/0-0. On delivery attempt: 0 caught:
org.apache.camel.RuntimeCamelException: java.io.IOException:Attempted read
on closed stream.
org.apache.camel.RuntimeCamelException: java.io.IOException: Attempted read
on closed stream.
        at
org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:411)
        at
org.apache.camel.impl.converter.InstanceMethodTypeConverter.convertTo(InstanceMethodTypeConverter.java:50)
        at
org.apache.camel.impl.converter.DefaultTypeConverter.convertTo(DefaultTypeConverter.java:67)
        at
org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:59)
        at
org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:50)
        at
org.apache.camel.processor.ConvertBodyProcessor.process(ConvertBodyProcessor.java:41)
        at
org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:69)
        at
org.apache.camel.processor.DeadLetterChannel.process(DeadLetterChannel.java:155)
        at
org.apache.camel.processor.DeadLetterChannel.process(DeadLetterChannel.java:91)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:85)
        at
org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:57)
        at
org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:39)
        at
org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:41)
        at
org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:66)
        at
org.apache.servicemix.camel.CamelJbiEndpoint.handleActiveProviderExchange(CamelJbiEndpoint.java:101)
        at
org.apache.servicemix.camel.CamelJbiEndpoint.process(CamelJbiEndpoint.java:74)
        at
org.apache.servicemix.common.AsyncBaseLifeCycle.doProcess(AsyncBaseLifeCycle.java:538)
        at
org.apache.servicemix.common.AsyncBaseLifeCycle.processExchange(AsyncBaseLifeCycle.java:490)
        at
org.apache.servicemix.common.BaseLifeCycle.onMessageExchange(BaseLifeCycle.java:46)
        at
org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBound(DeliveryChannelImpl.java:610)
        at
org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlow.java:172)
        at
org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.java:167)
        at
org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.java:134)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
        at java.lang.Thread.run(Thread.java:595)
Caused by: java.io.IOException: Attempted read on closed stream.
        at
org.apache.commons.httpclient.AutoCloseInputStream.isReadAllowed(AutoCloseInputStream.java:165)
        at
org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:85)
        at
org.apache.xerces.impl.XMLEntityManager$RewindableInputStream.read(Unknown
Source)
        at
org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
        at
org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown
Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
Source)
        at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
        at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
        at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
        at
org.apache.camel.converter.jaxp.XmlConverter.toDOMSourceFromStream(XmlConverter.java:366)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at
org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:407)
        ... 26 more
        
Please help me resolve this problem. This is acting as a blocker as we
cannot release with the DEBUG mode in log4j.xml

Sandeep.
-- 
View this message in context: http://www.nabble.com/RuntimeCamelException%3A-java.io.IOException%3AAttempted-read-on-closed-stream-tp18869452p18869452.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: integrate jetty and servicemix

Posted by Guillaume Nodet <gn...@gmail.com>.
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 <qu...@yahoo.com> 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 <tr...@gmail.com> wrote:
>
>> From: tpounds <tr...@gmail.com>
>> Subject: Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream
>> To: users@servicemix.apache.org
>> 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/

integrate jetty and servicemix

Posted by quan tran <qu...@yahoo.com>.
All,
I wonder if someone has some ideas on this.  Any advices or document are appriciated.
Thanks
Quan


--- On Thu, 9/4/08, tpounds <tr...@gmail.com> wrote:

> From: tpounds <tr...@gmail.com>
> Subject: Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream
> To: users@servicemix.apache.org
> 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.


      

Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream

Posted by tpounds <tr...@gmail.com>.
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.


Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream

Posted by sachin2008 <es...@gmail.com>.
Hi Sandeep, 

We also faced the same problem with http component.  servicemix-http returns
the response with source as StaxSource or DOMSource.and StaxSource messages
are giving inconsitent results.  I don't know the reason for this. 

But,  work around for this to get the message from the http  with DOMSource. 
For this purpose, add the following policy definition in the http endpoint
definition.

<http:policies> 
    <bean class="org.apache.servicemix.soap.handlers.dom.DomHandler"/>
</http:policies>

If we add the above policy to http endpoint, NM  contents will be in DOM
source and we can avoid this problem. 

If you find any other good solution let me know.



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
>> } 
>> 
> 
> 


-----
Cheers
Praveen Oruganti
"Think before you act and act on what you believe"
-- 
View this message in context: http://www.nabble.com/RuntimeCamelException%3A-java.io.IOException%3AAttempted-read-on-closed-stream-tp18869452p19313332.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream

Posted by sandeep reddy <sa...@in2m.com>.
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-tp18869452p18958002.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream

Posted by sandeep reddy <sa...@in2m.com>.
>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-tp18869452p18886701.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: RuntimeCamelException: java.io.IOException:Attempted read on closed stream

Posted by Gert Vanthienen <ge...@skynet.be>.
Sandeep,

Can you pinpoint the messages that are causing this error?  Is there 
anything special to them?  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).

Regards,

Gert

sandeep reddy wrote:
> Hi Servicemix-guys, 
>
> Following is the my use case message flow:
>
>             Client App <--> HTTPConsumerSu --> CamelSu <---> HTTPProviderSu
> <--> External App
>
> We are struggling with a problem having INFO level in log4j.xml for
> org.apache.servicemix logger and WARN levels for rest of all loggers.
> Problem was java.io.IOException: Stream closed. The message was not
> delivered to External App. Following is the link for forum discussion :
>
>     http://cwiki.apache.org/SM/discussion-forums.html#nabble-td18688010
>     
> The error is related to
> http://cwiki.apache.org/SM/javaioioexception-stream-closed.html and is
> occurring for us in ServiceMix-Camel component.
>
> It finally got resolved based on suggestion mentioned in the forum.
>
> But this time I am facing error after getting response from External
> application. The error log is:
>
>     com.ctc.wstx.exc.WstxIOException: Attempted read on closed stream.
>     at
> com.ctc.wstx.stax.WstxInputFactory.doCreateSR(WstxInputFactory.java:548)
>     at
> com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:604)
>     at
> com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:660)
>     at
> com.ctc.wstx.stax.WstxInputFactory.createXMLStreamReader(WstxInputFactory.java:331)
>     at
> org.apache.servicemix.jbi.jaxp.StAXSourceTransformer.toXMLStreamReader(StAXSourceTransformer.java:86)
>     at
> org.apache.servicemix.http.endpoints.DefaultHttpConsumerMarshaler.sendOut(DefaultHttpConsumerMarshaler.java:78)
>     at
> org.apache.servicemix.http.endpoints.HttpConsumerEndpoint.sendOut(HttpConsumerEndpoint.java:392)
>     at
> org.apache.servicemix.http.endpoints.HttpConsumerEndpoint.process(HttpConsumerEndpoint.java:273)
>     at
> org.apache.servicemix.http.HttpBridgeServlet.doPost(HttpBridgeServlet.java:71)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
>
> To solve the above problem I tried same way as Gert suggested having
> convertToBody(DOMSource.class) after to(.......) statement. 
> Camel configuration with the added changes is as follows :
>
>     
> 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
>
> After the above changes almost all working, but some times I am getting
> following exception:
>
> ERROR - DeadLetterChannel              - Failed delivery forexchangeId:
> ID-rsandeep/34384-1218012001777/0-0. On delivery attempt: 0 caught:
> org.apache.camel.RuntimeCamelException: java.io.IOException:Attempted read
> on closed stream.
> org.apache.camel.RuntimeCamelException: java.io.IOException: Attempted read
> on closed stream.
>         at
> org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:411)
>         at
> org.apache.camel.impl.converter.InstanceMethodTypeConverter.convertTo(InstanceMethodTypeConverter.java:50)
>         at
> org.apache.camel.impl.converter.DefaultTypeConverter.convertTo(DefaultTypeConverter.java:67)
>         at
> org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:59)
>         at
> org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:50)
>         at
> org.apache.camel.processor.ConvertBodyProcessor.process(ConvertBodyProcessor.java:41)
>         at
> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:69)
>         at
> org.apache.camel.processor.DeadLetterChannel.process(DeadLetterChannel.java:155)
>         at
> org.apache.camel.processor.DeadLetterChannel.process(DeadLetterChannel.java:91)
>         at org.apache.camel.processor.Pipeline.process(Pipeline.java:101)
>         at org.apache.camel.processor.Pipeline.process(Pipeline.java:85)
>         at
> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:57)
>         at
> org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:39)
>         at
> org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:41)
>         at
> org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:66)
>         at
> org.apache.servicemix.camel.CamelJbiEndpoint.handleActiveProviderExchange(CamelJbiEndpoint.java:101)
>         at
> org.apache.servicemix.camel.CamelJbiEndpoint.process(CamelJbiEndpoint.java:74)
>         at
> org.apache.servicemix.common.AsyncBaseLifeCycle.doProcess(AsyncBaseLifeCycle.java:538)
>         at
> org.apache.servicemix.common.AsyncBaseLifeCycle.processExchange(AsyncBaseLifeCycle.java:490)
>         at
> org.apache.servicemix.common.BaseLifeCycle.onMessageExchange(BaseLifeCycle.java:46)
>         at
> org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBound(DeliveryChannelImpl.java:610)
>         at
> org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlow.java:172)
>         at
> org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.java:167)
>         at
> org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.java:134)
>         at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
>         at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
>         at java.lang.Thread.run(Thread.java:595)
> Caused by: java.io.IOException: Attempted read on closed stream.
>         at
> org.apache.commons.httpclient.AutoCloseInputStream.isReadAllowed(AutoCloseInputStream.java:165)
>         at
> org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:85)
>         at
> org.apache.xerces.impl.XMLEntityManager$RewindableInputStream.read(Unknown
> Source)
>         at
> org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
>         at
> org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown
> Source)
>         at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
> Source)
>         at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
> Source)
>         at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
>         at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
>         at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
>         at
> org.apache.camel.converter.jaxp.XmlConverter.toDOMSourceFromStream(XmlConverter.java:366)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:585)
>         at
> org.apache.camel.util.ObjectHelper.invokeMethod(ObjectHelper.java:407)
>         ... 26 more
>         
> Please help me resolve this problem. This is acting as a blocker as we
> cannot release with the DEBUG mode in log4j.xml
>
> Sandeep.
>