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] [Created] (CXF-4356) Temp file deleted before returning the stream in CachedOutputStream

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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13290306#comment-13290306 ] 

Gonçalo Rodrigues commented on CXF-4356:
----------------------------------------

Daniel,

It is the {{javax.activation.DataHandler}} that calls the {{CachedOutputStream#getInputStream()}} through its datasource ({{AttachmentDatasource}} actually). The {{DataHandler}} is the data holder in my generated stub (request param).

The stream is already empty when I get it from the request param in my web service implementation class.
                
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Attachment: cxf-4356-reproducer.zip

I’ve attached a maven project that reproduces the described problem.

This project is composed of two web services:

* {{UploadService}} which has two operations ({{uploadFile}} and {{uploadFileWsCall}}) that do the same thing, they read an incoming file stream and return its size. The only difference between both operations is that the second one calls the {{call}} operation of other web service ({{DummyService}}) before reading the stream.
* {{DummyService}} which does nothing, it was made to be called from the {{uploadFileWsCall}} operation of {{UploadService}}.

The project has also two unit tests (integration tests in fact), to test both operations of the {{UploadService}}. The test consist on sending 10,000 times (1,000 times for the {{UploadFileAfterWsCallTest}}) the same file to the {{UploadService}} operation and check that the returning size match the real file size (130,700 bytes).

As we experienced, the {{UploadFileAfterWsCallTest}} fail after a few iterations. The returning file size is 0 (as the {{DataHandler}} gives an empty 	{{LoadingByteArrayOutputStream}} as {{InputStream}} implementation instead of the overrided {{FileInputStream}} from {{CachedOutputStream}}).

The {{UploadFileTest}} doesn't fail often but when it fails, it has the same symptoms as above.

This problem only occurs when MTOM is enabled.

To run the tests you only have to call "{{mvn clean test}}" – (make sure port 8080 is free as the tests start jetty on this port).

                
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>         Attachments: cxf-4356-reproducer.zip
>
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Daniel Kulp (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Daniel Kulp resolved CXF-4356.
------------------------------

       Resolution: Fixed
    Fix Version/s: 2.6.2
                   2.5.5
                   2.4.9
    
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>            Assignee: Daniel Kulp
>             Fix For: 2.4.9, 2.5.5, 2.6.2
>
>         Attachments: cxf-4356-reproducer.zip
>
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Description: 
I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 

After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.

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

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
			}
		}
		tempFile.delete();
		tempFile = null;
		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}} to delete the temp file.

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

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
			}
		}
		tempFile.delete();
		tempFile = null;
		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
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Daniel Kulp (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13415858#comment-13415858 ] 

Daniel Kulp commented on CXF-4356:
----------------------------------

I believe a simple patch of:

{code}
--- a/api/src/main/java/org/apache/cxf/io/CachedOutputStream.java
+++ b/api/src/main/java/org/apache/cxf/io/CachedOutputStream.java
@@ -464,9 +464,13 @@ public class CachedOutputStream extends OutputStream {
         } else {
             try {
                 FileInputStream fileInputStream = new FileInputStream(tempFile) {
+                    boolean closed;
                     public void close() throws IOException {
-                        super.close();
-                        maybeDeleteTempFile(this);
+                        if (!closed) {
+                            super.close();
+                            maybeDeleteTempFile(this);
+                        }
+                        closed = true;
                     }
                 };
                 streamList.add(fileInputStream);
{code}

will fix this.  I need to test this more though.  

Apparently, the FileInputStream.finalize method calls close a second time which, if not guarded as above, could cause the maybeDeleteTempFile to be called again and delete the file prematurely.
                
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>            Assignee: Daniel Kulp
>         Attachments: cxf-4356-reproducer.zip
>
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Daniel Kulp (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13290231#comment-13290231 ] 

Daniel Kulp commented on CXF-4356:
----------------------------------


Hold on... who is calling getInputStream() in this case?   The CachedOutputStream is specifically designed so that the caller of the getInputStream is supposed to hold onto it (or close it).   Thus, it shouldn't be garbage collected.  
                
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13288547#comment-13288547 ] 

Gonçalo Rodrigues edited comment on CXF-4356 at 6/5/12 7:09 AM:
----------------------------------------------------------------

When I remove the {{close}} overriding everything works fine. 

Replacing:
{code:java}
FileInputStream fileInputStream = new FileInputStream(tempFile) {
	public void close() throws IOException {
		super.close();
		maybeDeleteTempFile(this);
	}
};
{code} 

By:
{code:java}
FileInputStream fileInputStream = new FileInputStream(tempFile);
{code} 

But obviously the temp file is never deleted which is not correct!
                
      was (Author: goncalo):
    When I remove the {{close}} overriding everything works fine. 

Replacing:
{code:java}
FileInputStream fileInputStream = new FileInputStream(tempFile) {
	public void close() throws IOException {
		super.close();
		maybeDeleteTempFile(this);
	}
};
{code} 

By:
{code:java}
FileInputStream fileInputStream = new FileInputStream(tempFile);
{code} 

But obviously the temp file is not deleted which is not correct!
                  
> 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Daniel Kulp (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Daniel Kulp reassigned CXF-4356:
--------------------------------

    Assignee: Daniel Kulp
    
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>            Assignee: Daniel Kulp
>         Attachments: cxf-4356-reproducer.zip
>
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13415992#comment-13415992 ] 

Gonçalo Rodrigues commented on CXF-4356:
----------------------------------------

I just tried your patch and it seems to fix the problem.
                
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>            Assignee: Daniel Kulp
>         Attachments: cxf-4356-reproducer.zip
>
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
     [ 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}} to delete the temp file.

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

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
			}
		}
		tempFile.delete();
		tempFile = null;
		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());
		}
	}
}
{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
			}
		}
		tempFile.delete();
		tempFile = null;
		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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13288547#comment-13288547 ] 

Gonçalo Rodrigues commented on CXF-4356:
----------------------------------------

When I remove the {{close}} overriding everything works fine. 

Replacing:
{code:java}
FileInputStream fileInputStream = new FileInputStream(tempFile) {
	public void close() throws IOException {
		super.close();
		maybeDeleteTempFile(this);
	}
};
{code} 

By:
{code:java}
FileInputStream fileInputStream = new FileInputStream(tempFile);
{code} 

But obviously the temp file is not deleted which is not correct!
                
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
     [ 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
			}
		}
		tempFile.delete();
		tempFile = null;
		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());
		}
	}
}
{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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Affects Version/s: 2.6
    
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CXF-4356?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13289477#comment-13289477 ] 

Gonçalo Rodrigues commented on CXF-4356:
----------------------------------------

I found a workaround. If we keep the instance of the created {{FileInputStream}} in {{CachedOutputStream#getInputStream()}}, it prevents the GC to collect the {{FileInputStream}} instance too early and therefore to delete the temp file.

The temp file is still deleted but "later".

The {{CachedOutputStream}} (v.2.6) code change:
{code:java}
private FileInputStream fileInputStream; // <-- The instance we keep

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 = new FileInputStream(tempFile) { // <-- The instance we keep
                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} 
                
> 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, 2.6
>            Reporter: Gonçalo Rodrigues
>
> I’m implementing a web service to upload files (from 120 Kb to 1 Mb). Most of the time everything works fine, but sometimes (randomly) the uploaded file is empty (size == 0) in the target platform. 
> After some debugging I found that the problem comes from the temp file created by the {{CachedOutputStream}} that 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}} to delete the temp file.
> I tried to synchronize all the methods dealing with {{tempFile}} but it didn’t resolve my problem.
> 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
> 			}
> 		}
> 		tempFile.delete();
> 		tempFile = null;
> 		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

       

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

Posted by "Gonçalo Rodrigues (JIRA)" <ji...@apache.org>.
     [ 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