4 Replies Latest reply on Jan 16, 2014 3:12 AM by ivan_ra

    PortletBridge 2.3.1: memory leak on file upload using richfaces 3.x

    ivan_ra

      My application is working on JBoss portal 2.7, and I have to restart it every 3 weeks because out of memory error.

      I got memory dump, opened it in Eclipse Memory Analyzer and found many instances of org.ajax4jsf.request.MultipartRequest, which occupy most space of heap and saved in inner map of org.ajax4jsf.request.MultipartRequestRegistry.

      In Richfaces sources there is only 1 place where MultipartRequest is creating and it happens using try..finally block (BaseFilter.java):

       

      MultipartRequest multipartRequest = new MultipartRequest(httpRequest, createTempFiles, maxRequestSize, uid);

      ...

      try {

      ... some work with multipartRequest wrapper

      } finally {

        ...

        multipartRequest.clearRequestData();

      }

      Method multipartRequest.clearRequestData() removes multipartRequest instance from MultipartRequestRegistry, so Richfaces file upload alone has no leaks.

       

      But in PortletBridge sources i found code which creates MultipartRequest, works with it, but not removes it from MultipartRequestRegistry.

      This code is in RichFacesStrategy.java:

      - method handleFileuploadRequest creates MultipartRequest using reflection

      - but nowhere found call of multipartRequest.clearRequestData()

      So, every uploaded file (and his form) stay in memory until server restart.

        • 1. Re: PortletBridge 2.3.1: memory leak on file upload using richfaces 3.x
          kenfinni

          As it's been about 18 months since 2.3.1.Final was released, we're no longer actively developing that version.

           

          If you're unable to upgrade to Portlet Bridge 3, another option is for you to fix the memory leak yourself and build your own release of Portlet Bridge.

           

          Ken

          • 2. Re: PortletBridge 2.3.1: memory leak on file upload using richfaces 3.x
            ivan_ra

            Ken, use new components is good idea, but not in my case, because they will not work on jboss portal 2.7.

            So, I looked at bridge sources and suggest workaround.

            Helper class:

             

            public class BridgeHelper {

              public static PortletRequest getPortletRequest() {

                ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();

                Object request = ectx.getRequest();

                if (request != null && request instanceof PortletRequest)

                  return (PortletRequest)request;

                return null;

              }

             

              public static void clearRequestData() {

                PortletRequest request = BridgeHelper.getPortletRequest();

                if (request != null) {

                  Object multipartRequest = request.getAttribute("org.ajax4jsf.request.MultipartRequest");

                  if (multipartRequest != null) try {

                    Method m = multipartRequest.getClass().getMethod("clearRequestData", new Class[]{});

                    m.invoke(multipartRequest);

                  } catch (Exception ignored) {}

                }

              }

            }

            (I used reflection to escape richfaces dependency)

            And workaround in handler method:

             

              public void upload(UploadEvent event) throws IOException{

                uploadItem = event.getUploadItem();

                BridgeHelper.clearRequestData();

              }

             

            Now I will trace memory using and do report about problem solving.

            Maybe later do the same in RichFacesStrategy class. I think method afterResourceRequestExecute is good candidate for patch

            • 3. Re: PortletBridge 2.3.1: memory leak on file upload using richfaces 3.x
              kenfinni

              Ivan,

               

              I don't have much experience with that version of the code, so wouldn't be able to make any recommendations about the best approach on how to resolve the problem.

               

              And to be clear, we won't be releasing any new versions of Portlet Bridge 2.x, so any fixes you create would need to be built by yourself into a release.

               

              Ken

              • 4. Re: PortletBridge 2.3.1: memory leak on file upload using richfaces 3.x
                ivan_ra

                Successfully tested - this leak gone.

                I have made patch for org.jboss.portletbridge.richfaces.RichFacesStrategy class. I think the better place for patch is method afterResourceRequest because it called from finally block and will clear MultipartRequestRegistry always, even on errors. So, new code for this method looks like this:

                 

                  public void afterResourceRequest(FacesContext facesContext,

                      ResourceResponse wrappedResponse) {

                    finishResponse(facesContext,

                        (BufferedMimeResponseWrapper) wrappedResponse);

                    // clear MultipartRequestRegistry:

                    PortletRequest request = (PortletRequest)facesContext.getExternalContext().getRequest();

                    MultipartRequest multipartRequest = (MultipartRequest)request

                        .getAttribute(FileUploadConstants.FILE_UPLOAD_REQUEST_ATTRIBUTE_NAME);

                    if (multipartRequest != null)

                      multipartRequest.clearRequestData();

                  }

                 

                I upload patched library and sources, maybe it will help people who still works with Jboss Portal