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