Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-18364

AssetRenderer fails for Journal/Web Content utilising template when embeded in custom portlet due to incorrect class loader

    Details

      Description

      Description:

      Using the AssetRenderer to display Journal/Web Content in a custom portlet results in a null pointer when the Web Content has an associated Template.

      This is because the template parser com.liferay.portal.kernel.templateparser.BaseTransformer attempts to lookup the Template Parser with the following code:

      Line 147 of BaseTransformer.java
      templateParser =(TemplateParser)InstanceFactory.newInstance(templateParserClassName);

      This results in the InstanceFactory getting the class loader from the current thread:
      Line 47 of InstanceFactory.java
      Thread currentThread = Thread.currentThread();

      The class loader for the current thread will be the class loader for the custom portlet, thus the expected classes will not be available and an exception:
      com.liferay.portal.kernel.templateparser.TransformException:
      java.lang.ClassNotFoundException: com.liferay.portlet.journal.util.VelocityTemplateParser

      will be generated.

      Fortunately the InstanceFactory.newInstance(..) call can be passed a class loader, so modification of
      Line 147 of BaseTransformer.java to:

      templateParser=(TemplateParser)InstanceFactory.newInstance(
      PortalClassLoaderUtil.getClassLoader(),
      templateParserClassName);

      i.e. passing in the PortalClassLoader fixes the issue.

      Step to reproduce:

      1. Create a structure and template for web content.
      2. Add an instance of web content using the new structure and template.
      3. Write a custom portlet that attempt to display the data using the AssetRenderer in FULL, i.e. AssetRenderer.TEMPLATE_FULL_CONTENT

      example code:

      <%
      AssetRendererFactory af = AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName( JournalArticle.class.getName());

      AssetRenderer assetRenderer=af.getAssetRenderer('articleId');
      String renderPath=assetRenderer.render(portletRequest, portletResponse, AssetRenderer.TEMPLATE_FULL_CONTENT);
      String renderPortletId = AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName( JournalArticle.class.getName()).getPortletId()
      <liferay-util:include page="<%=renderPath%>" portletId="<%=renderPortletId %>" />

      4. View custom portlet (sometimes it will work on the first view)
      5. Refresh page - null pointer will occur in "html\portlet\journal\asset\full_content.jsp" at line 43 as the articleDisplay object is null due to the above exception.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              mark.jin Mark Jin (Inactive)
              Reporter:
              richard.gibson Richard Gibson (Inactive)
              Participants of an Issue:
              Recent user:
              Marta Elicegui
              Votes:
              4 Vote for this issue
              Watchers:
              11 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Days since last comment:
                9 years, 26 weeks, 1 day ago

                  Packages

                  Version Package
                  6.1.1 CE GA2
                  6.1.20 EE GA2
                  6.2.0 CE M2