Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InputStream closed too late leading to file handler leakage until garbage collection #6

Open
99sono opened this issue Jun 2, 2015 · 0 comments

Comments

@99sono
Copy link

99sono commented Jun 2, 2015

Hi there,

On the branch 1.0.0 and probably across the upper branches as well, the ImageResourceHandler is not closing the StreamedContent input stream, unlike - as we've seen in the incorrect issue I opened before - prime faces does in its resource handler.

The ImageResourceHandler is pumping out the data of the streamed content and then it is done.

added a closeStreamContent,

'''
@OverRide
public void handleResourceRequest(FacesContext context) throws IOException {
Map<String, String> params = context.getExternalContext().getRequestParameterMap();
String library = params.get("ln");
String dynamicContentId = params.get(Constants.DYNAMIC_CONTENT_PARAM);

    if (dynamicContentId != null && library != null && library.equals("advancedPrimefaces")) {
        GraphicImageManager graphicImageManager = GraphicImageUtil.retrieveManager(context);
        StreamedContent streamedContent = graphicImageManager.retrieveImage(dynamicContentId);

        try {
            ExternalContext externalContext = context.getExternalContext();
            externalContext.setResponseStatus(200);
            externalContext.setResponseContentType(streamedContent.getContentType());

            byte[] buffer = new byte[2048];

            int length;
            InputStream inputStream = streamedContent.getStream();
            while ((length = (inputStream.read(buffer))) >= 0) {
                externalContext.getResponseOutputStream().write(buffer, 0, length);
            }

            externalContext.responseFlushBuffer();
            context.responseComplete();
        } finally {
            // ensures the JVM will not be keeping file handler for the tmp file
            closeStreamContent(streamedContent);
        }

    } else {
        // this is desirable path - we are not dealing with advanced graphic rendering and
        // we allow the defualt primefaces implementation to take over
        getWrapped().handleResourceRequest(context);
    }

}

/**
 * Ensure that we do not leave the java vm process keeping alive a file pointer the tmp file.
 *
 * @param streamedContent
 *            a stream created to feed to the browser the tmp file
 */
private void closeStreamContent(StreamedContent streamedContent) {
    try {
        if (streamedContent != null) {
            streamedContent.getStream().close();
        }
    } catch (Exception e) {
        LOGGER.log(
                Level.SEVERE,
                "Unexpected error took while attempting to close the streamed cotent of temporary file associated to the advanced graphic image renderer",
                e);
    }
}

'''

Using process explorer.exe I can now check that after the labrado page is rendered to the user the TMP files created on the TMP folder are not held up open.

Kindest regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant