Lukasz
Lukasz

Reputation: 721

File not found exception for temporary files

I'm building java app (Spring & JSF & PrimeFaces). I upload a file to the server, however, if I click "next" button right after the file upload ends, I get this error:

Aug 24, 2013 8:12:34 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/codekata] threw exception [Request processing failed; nested exception is org.springframework.webflow.execution.repository.FlowExecutionRestorationFailureException: A problem occurred restoring the flow execution with key 'e1s3'] with root cause
java.io.FileNotFoundException: C:\Users\Luke\AppData\Local\Temp\upload__6f71235a_140b1bdd246__8000_00000011.tmp (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at org.apache.commons.fileupload.disk.DiskFileItem.readObject(DiskFileItem.java:709)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1891)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
     java.lang.Thread.run(Thread.java:722)

If I wait a couple of seconds, all works fine. I assume that the upload file needs to have time to copy itself to the temporary folder, does anyone have an idea how to resolve this problem. I use Tomcat 7.

Here is my download method:

public StreamedContent getDownloadFile()
    {
        InputStream inputStream = new ByteArrayInputStream(selectedBook.getBookText().getText().getBytes());
        return new DefaultStreamedContent(inputStream, "text/plain", selectedBook.getTitle() + ".txt", BookBean.encoding);
    }

Thanks, Luke.

Upvotes: 5

Views: 9386

Answers (2)

BalusC
BalusC

Reputation: 1109072

Based on the stack trace, it looks like that you're storing the UploadedFile instance as a property of a class which is by itself Serializable. This is not right. You should be grabbing the uploaded file content immediately in the <p:fileUpload handleFileUpload> file upload listener method (or the submit button in case you are using <p:fileUpload mode="simple">). Store it at a more permanent location. E.g. the local disk file system, or the database, or maybe even as a byte[] bean property. And then pass the local disk file system filename, or database PK, or the byte[] around instead in order to have a handle to download the file back.

Summarized, just make sure that your Serializable backing bean is completely free of a UploadedFile property and this problem shall disappear.

Upvotes: 10

victorantunes
victorantunes

Reputation: 1169

Without any code, the first thing that comes to mind would be to synchronize threads, so that your button action will wait for the upload process to finish.

EDIT: From the way you're describing it, your action is apparently being called too soon, so that the file hasn't yet been properly written.

One way to get around this would be to check if the file exists:

File file = new File(<path_to_tmp_file>);
  if(file.exists()){
    //Download file
  }

Upvotes: 1

Related Questions