Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-4356

Temp file deleted before returning the stream in CachedOutputStream

Agile BoardAttach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.5, 2.6
    • 2.4.9, 2.5.5, 2.6.2
    • None
    • None
    • Unknown

    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:

      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	
      

      The getInputStream method:

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

      The maybeDeleteTempFile method:

      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;
      	}
      }
      

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            dkulp Daniel Kulp
            goncalo Gonçalo Rodrigues
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment