You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org> on 2012/06/04 13:48:34 UTC

[jira] [Updated] (CXF-4356) Temp file deleted before returning the stream in CachedOutputStream

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

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

    Description: 
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());
		}
	}
}
{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} 

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

    
> 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());
> 		}
> 	}
> }
> {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