Rittel
Rittel

Reputation: 589

Primefaces is not immediately closing the stream of DefaultStreamedContent after read

I have the following problem:

I am displaying an image in my webapp using a <p:graphicImage> from Primefaces

The image displayed is delivered by a bean as a DefaultStreamedContent. In my application I am sometimes deleting images displayed this way during runtime.

This always takes a little time till I can delete the image. After debugging a little i used the Files.delete of Java 7 and got the following exception:

The process cannot access the file because it is being used by another process.

I thus suspect that Primefaces is not immediately closing the stream behind the DefaultStreamedContent after displaying and i am not able to delete the file whenever I want.

Is there any way to tell the DefaultStreamedContent to close itself imediately after read (I already looked into the documentation and didn't find any fitting method within the DefaultStreamedContent, but maybe one can tell the stream or something like that?)

Upvotes: 3

Views: 4653

Answers (1)

Rittel
Rittel

Reputation: 589

Ok I finally found out what is happening using the Unlocker tool

(can be downloaded here: http://www.emptyloop.com/unlocker/#download)

I saw that the java.exe is locking the file once it is displayed. Therefor the Stream behind the StreamedContent is NOT immediately closed after reading.

My solution was as follows:

I made a superclass extending the StreamedContent and let it read the inputstream and "feed" the read bytes into a new InputStream. After that i closed the given stream so that the ressource behind it is released again.

the class looks something like this:

public class PersonalStreamedContent extends DefaultStreamedContent {

/**
 * Copies the given Inputstream and closes it afterwards
 */
public PersonalStreamedContent(FileInputStream stream, String contentType) {
    super(copyInputStream(stream), contentType);
}

public static InputStream copyInputStream(InputStream stream) {
    if (stream != null) {
        try {
            byte[] bytes = IOUtils.toByteArray(stream);
            stream.close();
            return new ByteArrayInputStream(bytes);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        System.out.println("inputStream was null");
    }
    return new ByteArrayInputStream(new byte[] {});
}
}

I am quite sure that the image is retrieved 2 times by Primefaces but only closed the FIRST time it is loaded. I didn't realize this in the beginning.

I hope this can help some other people too :)

Upvotes: 5

Related Questions