camel-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Willem Jiang (JIRA)" <j...@apache.org>
Subject [jira] Commented: (CAMEL-2636) IOException: Bad file descriptor and FileNotFoundException
Date Fri, 16 Apr 2010 06:58:28 GMT

    [ https://issues.apache.org/activemq/browse/CAMEL-2636?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=58897#action_58897
] 

Willem Jiang commented on CAMEL-2636:
-------------------------------------

Hi Raymond 

I reviewed the change, and found your don't delete the file unless the CachedOutputStream
is closed. 
If the CachedOutputStream is not closed after the exchange is processed, there could be lots
of temp file. 
Can I see the route that you get the filenotfoundexception?

> IOException: Bad file descriptor and FileNotFoundException
> ----------------------------------------------------------
>
>                 Key: CAMEL-2636
>                 URL: https://issues.apache.org/activemq/browse/CAMEL-2636
>             Project: Apache Camel
>          Issue Type: Bug
>          Components: camel-core
>    Affects Versions: 2.2.0
>         Environment: Related to topic, I will post possible solution to this problem:
> http://old.nabble.com/bridging-binary-files-over-http-ts28178639.html
> Other useful links:
> http://256.com/gray/docs/misc/java_bad_file_descriptor_close_bug.shtml
> My environment:
> apache 2.2.0
> java version "1.6.0_19"
> Java(TM) SE Runtime Environment (build 1.6.0_19-b04)
> Java HotSpot(TM) 64-Bit Server VM (build 16.2-b04, mixed mode)
> no container, using:
> mvn camel:run
> java.io.IOException: Bad file descriptor
>         at java.io.FileInputStream.available(Native Method)
>         at org.apache.camel.converter.stream.FileInputStreamCache.available(FileInputStreamCache.java:70)
>         at org.apache.camel.util.IOHelper.copy(IOHelper.java:85)
>         at org.apache.camel.util.IOHelper.copy(IOHelper.java:81)
>         at org.apache.camel.component.http.DefaultHttpBinding.doWriteDirectResponse(DefaultHttpBinding.java:183)
>         at org.apache.camel.component.http.DefaultHttpBinding.doWriteResponse(DefaultHttpBinding.java:169)
>         at org.apache.camel.component.http.DefaultHttpBinding.writeResponse(DefaultHttpBinding.java:116)
>         at org.apache.camel.component.http.CamelServlet.service(CamelServlet.java:61)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
>         at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
>         at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
>         at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>         at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
>         at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>         at org.mortbay.jetty.Server.handle(Server.java:326)
>         at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
>         at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
>         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
>         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
>         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>         at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>         at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

> Config:
> <?xml version="1.0" encoding="UTF-8"?>
> <beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xmlns="http://camel.apache.org/schema/spring" xmlns:cxf="http://camel.apache.org/schema/cxf"
>     xsi:schemaLocation="
>        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
>        http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
>        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
>     <camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring"
trace="true" autoStartup="true">
>         <!-- clipboard download producer -->
>         <route>
>             <from uri="jetty:http://0.0.0.0:8201/clipboard/download?chunked=true&amp;matchOnUriPrefix=true"
/>
>             <to uri="http://0.0.0.0:9101?bridgeEndpoint=true" async="false" />
>         </route>
>     </camelContext>
> </beans:beans>
>            Reporter: raymond domingo
>            Assignee: Willem Jiang
>             Fix For: Future
>
>   Original Estimate: 1 hour
>  Remaining Estimate: 1 hour
>
> When I try to stream BINARY (pdf) file using camel-http I get the java.io.IOException:
Bad file descriptor
> The pdf isn't recieved succesfully by reciever (0kb)
> This seems to be caused by a bug in java (on linux systems), closing inputstream twice
causes problems. It seemed to me this is exactly what is happening, see also link:
> http://256.com/gray/docs/misc/java_bad_file_descriptor_close_bug.shtml
> I fixed this by (checking out apache camel-core and camel-http 2.2.0):
> In FileInputStreamCache.java:
> In method close() wrapped getInputStream().close() in if:
> if (stream != null && stream instanceof FileInputStream && ((FileInputStream)
stream).getChannel().isOpen()) {
> getInputStream().close() ;
> }
> In method reset() also:
> if (stream != null && stream instanceof FileInputStream && ((FileInputStream)
stream).getChannel().isOpen()) {
> getInputStream().close() ;
> }
> Second I needed to fix a filenotfoundexception, the tempfile created by camel was deleted
to early.
> I changed CachedOutputStream.java
> - Reimplemented constructor:
> public CachedOutputStream(Exchange exchange) {
>         String hold = exchange.getContext().getProperties().get(THRESHOLD);
>         String dir = exchange.getContext().getProperties().get(TEMP_DIR);
>         if (hold != null) {
>             this.threshold = exchange.getContext().getTypeConverter().convertTo(Long.class,
hold);
>         }
>         if (dir != null) {
>             this.outputDir = exchange.getContext().getTypeConverter().convertTo(File.class,
dir);
>         }
>         // add on completion so we can cleanup after the exchange is done such
>         // as deleting temporary files
>         exchange.addOnCompletion(new SynchronizationAdapter() {
>             @Override
>             public void onDone(Exchange exchange) {
>                 try {
>                     // close the stream and FileInputStreamCache
>                     // close();
>                     // for (FileInputStreamCache cache : fileInputStreamCaches)
>                     // {
>                     // cache.close();
>                     // }
>                     // cleanup temporary file
>                     if (tempFile != null) {
>                         System.err.println("####################################################");
>                         System.err.println("DISABLED tempFile.delete:89");
>                         System.err.println("####################################################");
>                         // boolean deleted = tempFile.delete();
>                         // if (!deleted) {
>                         // LOG.warn("Cannot delete temporary cache file: " +
>                         // tempFile);
>                         // } else if (LOG.isTraceEnabled()) {
>                         // LOG.trace("Deleted temporary cache file: " +
>                         // tempFile);
>                         // }
>                         tempFile = null;
>                     }
>                 } catch (Exception e) {
>                     LOG.warn("Error deleting temporary cache file: " + tempFile, e);
>                 }
>             }
>             @Override
>             public String toString() {
>                 return "OnCompletion[CachedOutputStream]";
>             }
>         });
>     }
> Reimplemented close():
> public void close() throws IOException {
>         System.err.println("####################################################");
>         System.err.println("outputStream.close:119 -> delete tempFile");
>         System.err.println("####################################################");
>         new Exception().printStackTrace();
>         currentStream.close();
>         boolean deleted = tempFile.delete();
>         if (!deleted) {
>             LOG.warn("Cannot delete temporary cache file: " + tempFile);
>         } else if (LOG.isTraceEnabled()) {
>             LOG.trace("Deleted temporary cache file: " + tempFile);
>         }
>     }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/activemq/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message