Gonçalo Rodrigues created CXF-4356:
--------------------------------------

             Summary: Temp file deleted before returning the stream in 
CachedOutputStream
                 Key: CXF-4356
                 URL: https://issues.apache.org/jira/browse/CXF-4356
             Project: CXF
          Issue Type: Bug
    Affects Versions: 2.5
            Reporter: Gonçalo Rodrigues


Sometimes (randomly) the temp file is deleted during the process of getting the 
cached stream. In fact, {{maybeDeleteTempFile}} is called before 
{{getInputStream}} which returns an empty {{LoadingByteArrayOutputStream}}. The 
{{finalize}} method of {{FileInputStream}} calls its {{close}} method which is 
overridden in {{CachedOutputStream#getInputStream}}.

I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t 
resolve my problem - but it happens less often.

The stack: 

{code}
Daemon System Thread [Finalizer] (Suspended (breakpoint at line 490 in 
CachedOutputStream))     
        CachedOutputStream.maybeDeleteTempFile(Object) line: 490        
        CachedOutputStream.access$000(CachedOutputStream, Object) line: 43      
        CachedOutputStream$1.close() line: 469  
        CachedOutputStream$1(FileInputStream).finalize() line: 381      
        Finalizer.invokeFinalizeMethod(Object) line: not available [native 
method]      
        Finalizer.runFinalizer() line: 83       
        Finalizer.access$100(Finalizer) line: 14        
        Finalizer$FinalizerThread.run() line: 160       
{code} 

The {{getInputStream}} method: 

{code:java}
public InputStream getInputStream() throws IOException {
        flush();
        if (inmem) {
                if (currentStream instanceof LoadingByteArrayOutputStream) {
                        return ((LoadingByteArrayOutputStream) 
currentStream).createInputStream();
                } else if (currentStream instanceof ByteArrayOutputStream) {
                        return new 
ByteArrayInputStream(((ByteArrayOutputStream) currentStream).toByteArray());
                } else if (currentStream instanceof PipedOutputStream) {
                        return new PipedInputStream((PipedOutputStream) 
currentStream);
                } else {
                        return null;
                }
        } else {
                try {
                        FileInputStream fileInputStream = new 
FileInputStream(tempFile) {
                                public void close() throws IOException {
                                        super.close();
                                        maybeDeleteTempFile(this);
                                }
                        };
                        streamList.add(fileInputStream);
                        return fileInputStream;
                } catch (FileNotFoundException e) {
                        throw new IOException("Cached file was deleted, " + 
e.toString());
                }
        }
}

private void maybeDeleteTempFile(Object stream) {
        streamList.remove(stream);
        if (!inmem && tempFile != null && streamList.isEmpty() && 
allowDeleteOfFile) {
                if (currentStream != null) {
                        try {
                                currentStream.close();
                                postClose();
                        } catch (Exception e) {
                                //ignore
                        }
                }
                deleteTempFile();
                currentStream = new LoadingByteArrayOutputStream(1024);
                inmem = true;
        }
}
{code} 


The {{maybeDeleteTempFile}} method: 

{code:java}
private void maybeDeleteTempFile(Object stream) {
        streamList.remove(stream);
        if (!inmem && tempFile != null && streamList.isEmpty() && 
allowDeleteOfFile) {
                if (currentStream != null) {
                        try {
                                currentStream.close();
                                postClose();
                        } catch (Exception e) {
                                //ignore
                        }
                }
                deleteTempFile();
                currentStream = new LoadingByteArrayOutputStream(1024);
                inmem = true;
        }
}
{code} 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira


Reply via email to