You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by "Willem Jiang (JIRA)" <ji...@apache.org> on 2010/05/20 07:30:16 UTC

[jira] Commented: (CAMEL-2636) IOException: Bad file descriptor and FileNotFoundException

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

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

Hi Roland,
We fix this issue of camel jetty and http component by not letting camel remove the temp file at the end of the route,
If you call the "exchange.getIn().getBody(String.class)" in your processor, the cached input stream will be closed, and temp file will be removed.
As you consumed the inputStream, you'd better reset the body with the String that your get.


> 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: 2.3.0
>
>   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.
-
You can reply to this email to add a comment to the issue online.