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/04/16 05:37:27 UTC

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

     [ https://issues.apache.org/activemq/browse/CAMEL-2636?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Willem Jiang reassigned CAMEL-2636:
-----------------------------------

    Assignee: Willem Jiang

> 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