Details

    • Similar Issues:
      None

      Description

      Setting the following in portlet.xml
      <container-runtime-option>
      <name>javax.portlet.actionScopedRequestAttributes</name>
      <value>true</value>
      </container-runtime-option>

      should enable any attributes set into the portletRequest during the action phase to be available in the render phase, and subsequent render calls until another event/action method is called.

      Currently setting a portletRequest attribute in the action phase with this property set, does not make the attribute available on subsequent calls to render. So the key issue here is that when the portlet container tells the portlet that it needs to re-render, usually as a result of a user interacting with another portlet on the page, then the request attributes are lost.

        Issue Links

          Activity

          Richard Gibson created issue -
          Vicki Tsang made changes -
          Field Original Value New Value
          Workflow Liferay Workflow 2.2 [ 250107 ] LPS Workflow [ 263048 ]
          Hide
          Mark A. Ziesemer added a comment -

          All of the following Liferay forum threads appear to closely relate to this issue, and are all considered unresolved:

          setAttribute in ProcessEvent() 2008-10-06
          action scoped request attributes 2008-10-17
          Best way to pass information from 'processEvent' to render ('view') 2009-05-18
          Container Runtime option - actionScopedRequestAttributes 2010-09-28
          Pass objects from processEvent to doView 2011-11-28


          Especially as Liferay further encourages adoption of JSF (with Liferay Faces, etc.) - which I agree, is a desired and necessary goal - I believe this issue requires renewed and priority attention, for what shouldn't be too complex of a fix.

          This issue is actually not specific to the MVCPortlet, and applies to any JSR-286 portlet implementation.

          I am not currently aware of an acceptable work-around for this, but would be interested in any temporary work-arounds that Liferay may have to offer.

          Here is the beginnings of a test case that should be possible:

          import java.io.IOException;
          import java.io.PrintWriter;
          
          import javax.portlet.Event;
          import javax.portlet.EventRequest;
          import javax.portlet.EventResponse;
          import javax.portlet.GenericPortlet;
          import javax.portlet.PortletException;
          import javax.portlet.ProcessEvent;
          import javax.portlet.RenderRequest;
          import javax.portlet.RenderResponse;
          
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          
          public class PortletDemo extends GenericPortlet{
          	
          	protected static final Logger LOGGER = LoggerFactory.getLogger(PortletDemo.class);
          	
          	@ProcessEvent(name="test-event")
          	public void handleContactEvent(EventRequest request, EventResponse response) throws PortletException, IOException{
          		Event e = request.getEvent();
          		LOGGER.info("Got test-event: {}", e);
          		
          		// Save event to retrieve properties from during render:
          		request.setAttribute("test-event", e);
          	}
          	
          	@Override
          	protected void doView(RenderRequest request, RenderResponse response) throws PortletException,
          			IOException{
          		
          		PrintWriter pw = response.getWriter();
          		pw.println("<p>test-event: " + request.getAttribute("test-event") + "</p>");
          	}
          	
          }
          

          As-is, this does not work, due to the issue reported here. Even setting "javax.portlet.actionScopedRequestAttributes" to true does not help.

          One naive approach that I am starting to see as a common work-around is to add an instance variable, e.g. "protected Object testEvent;" - which is assigned to from the event method, and read from the "doView" method. However, this is not thread-safe, and will lead to issues under a loaded system. Another approach may be to use a ThreadLocal - which will solve the thread safety concerns, but could lead to memory leaks, and/or accidental re-use of any stored events due to thread pooling/re-use.

          Show
          Mark A. Ziesemer added a comment - All of the following Liferay forum threads appear to closely relate to this issue, and are all considered unresolved: setAttribute in ProcessEvent() 2008-10-06 action scoped request attributes 2008-10-17 Best way to pass information from 'processEvent' to render ('view') 2009-05-18 Container Runtime option - actionScopedRequestAttributes 2010-09-28 Pass objects from processEvent to doView 2011-11-28 Especially as Liferay further encourages adoption of JSF (with Liferay Faces, etc.) - which I agree, is a desired and necessary goal - I believe this issue requires renewed and priority attention, for what shouldn't be too complex of a fix. This issue is actually not specific to the MVCPortlet, and applies to any JSR-286 portlet implementation. I am not currently aware of an acceptable work-around for this, but would be interested in any temporary work-arounds that Liferay may have to offer. Here is the beginnings of a test case that should be possible: import java.io.IOException; import java.io.PrintWriter; import javax.portlet.Event; import javax.portlet.EventRequest; import javax.portlet.EventResponse; import javax.portlet.GenericPortlet; import javax.portlet.PortletException; import javax.portlet.ProcessEvent; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PortletDemo extends GenericPortlet{ protected static final Logger LOGGER = LoggerFactory.getLogger(PortletDemo.class); @ProcessEvent(name= "test-event" ) public void handleContactEvent(EventRequest request, EventResponse response) throws PortletException, IOException{ Event e = request.getEvent(); LOGGER.info( "Got test-event: {}" , e); // Save event to retrieve properties from during render: request.setAttribute( "test-event" , e); } @Override protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException{ PrintWriter pw = response.getWriter(); pw.println( "<p>test-event: " + request.getAttribute( "test-event" ) + "</p>" ); } } As-is, this does not work, due to the issue reported here. Even setting " javax.portlet.actionScopedRequestAttributes " to true does not help. One naive approach that I am starting to see as a common work-around is to add an instance variable, e.g. " protected Object testEvent; " - which is assigned to from the event method, and read from the " doView " method. However, this is not thread-safe, and will lead to issues under a loaded system. Another approach may be to use a ThreadLocal - which will solve the thread safety concerns, but could lead to memory leaks, and/or accidental re-use of any stored events due to thread pooling/re-use.
          Hide
          Mark A. Ziesemer added a comment -

          I've opened an EE support ticket to hopefully bring some additional attention to this. Along with a complete test case I provided there, I provided the following notes which are of particular concern - in regards to compliance with the JRS-286 Portlet Specification 2.0:

          Note that per http://portlet-container.java.net/docs/jsr286.html#Container_runtime_options (emphasis mine):

          javax.portlet.actionScopedRequestAttributes : The servlet based applications assume that attributes that they set in the action phase will be accessible again when starting the rendering. The Portlet Specification provides the render parameters for such use cases, but some applications need to transport complex objects instead of strings. For such use cases the Portlet Specification provides the action-scoped request attributes as container runtime option. If this option is set to true, any complex object set as a request attribute in the action or event phase is available in the render phase. These attributes can be accessed by the portlets until a new action occurs.

          Please also refer to "PLT.10.4 Portlet Container Runtime Options" in the portlet specification (emphasis mine):

          Container runtime options besides the javax.portlet.actionScopedRequestAttributes option are optional to support by the portlet container and the portlet can find out which container runtime options are supported by the portlet container running the portlet via the method getContainerRuntimeOptions on the PortletContext.

          Another thing I noticed while testing is that changing this container option between "true" and "false" doesn't seem to have ANY impact. I.E., changing it to "false" should prevent attributes from being passed between the action and render phases - but it doesn't. (Where we're currently unable to get attributes to be passed between the event and render phases at all - regardless of this container option.)

          Show
          Mark A. Ziesemer added a comment - I've opened an EE support ticket to hopefully bring some additional attention to this. Along with a complete test case I provided there, I provided the following notes which are of particular concern - in regards to compliance with the JRS-286 Portlet Specification 2.0: Note that per http://portlet-container.java.net/docs/jsr286.html#Container_runtime_options (emphasis mine): javax.portlet.actionScopedRequestAttributes : The servlet based applications assume that attributes that they set in the action phase will be accessible again when starting the rendering. The Portlet Specification provides the render parameters for such use cases, but some applications need to transport complex objects instead of strings. For such use cases the Portlet Specification provides the action-scoped request attributes as container runtime option. If this option is set to true, any complex object set as a request attribute in the action or event phase is available in the render phase. These attributes can be accessed by the portlets until a new action occurs. Please also refer to "PLT.10.4 Portlet Container Runtime Options" in the portlet specification (emphasis mine): Container runtime options besides the javax.portlet.actionScopedRequestAttributes option are optional to support by the portlet container and the portlet can find out which container runtime options are supported by the portlet container running the portlet via the method getContainerRuntimeOptions on the PortletContext. Another thing I noticed while testing is that changing this container option between "true" and "false" doesn't seem to have ANY impact. I.E., changing it to "false" should prevent attributes from being passed between the action and render phases - but it doesn't. (Where we're currently unable to get attributes to be passed between the event and render phases at all - regardless of this container option.)
          Hide
          Arthur Hsiao (Inactive) added a comment - - edited

          This issue is talking about the same implementation within LPS-29134

          Show
          Arthur Hsiao (Inactive) added a comment - - edited This issue is talking about the same implementation within LPS-29134
          Arthur Hsiao (Inactive) made changes -
          Link This issue is duplicated by LPS-29134 [ LPS-29134 ]
          Andrew Kim made changes -
          Workflow LPS Workflow [ 263048 ] Copy of LPS Workflow [ 404382 ]
          Andrew Kim made changes -
          Workflow Copy of LPS Workflow [ 404382 ] LPS Workflow [ 436002 ]
          Andrew Kim made changes -
          Workflow LPS Workflow [ 436002 ] Copy 2 of LPS Workflow [ 468301 ]
          Andrew Kim made changes -
          Workflow Copy 2 of LPS Workflow [ 468301 ] LPS Workflow [ 500197 ]
          Hide
          Simone Taliercio added a comment -

          Hello Guys and Liferay Team,
          I'm stuck in the same situation: Portlet A in Page1 fires an event. Portlet B in page2 catches the event.
          The event method is managed through Annotation @ProcessEvent. From this method I would like to share an attribute with the related JSP, but the renderRequest doesn't contain the parameter previously set.

          Kind Regards,
          Simone Taliercio

          Show
          Simone Taliercio added a comment - Hello Guys and Liferay Team, I'm stuck in the same situation: Portlet A in Page1 fires an event. Portlet B in page2 catches the event. The event method is managed through Annotation @ProcessEvent. From this method I would like to share an attribute with the related JSP, but the renderRequest doesn't contain the parameter previously set. Kind Regards, Simone Taliercio
          Edward Gonzales made changes -
          Component/s Tools [ 14532 ]
          Hide
          Aniceto P Madrid added a comment -

          Richard
          I've previously used com.liferay.portal.kernel.portlet.LiferayPortlet to create portlets. Truth is after an action, render is called only once (as far as you remain in the same page and don't use public render parameters or events) because Liferay renders from cache the 2nd time and subsequents.
          Anyway, Can you tell me if this still happens in 6.2.0m4? Here you can download sdk and bundles http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.2.0%20M4/
          Thanks

          Show
          Aniceto P Madrid added a comment - Richard I've previously used com.liferay.portal.kernel.portlet.LiferayPortlet to create portlets. Truth is after an action, render is called only once (as far as you remain in the same page and don't use public render parameters or events) because Liferay renders from cache the 2nd time and subsequents. Anyway, Can you tell me if this still happens in 6.2.0m4? Here you can download sdk and bundles http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.2.0%20M4/ Thanks
          Aniceto P Madrid made changes -
          Labels community-verifier
          Hide
          Aniceto P Madrid added a comment -

          This issue can no longer be reproducible. I suggest this be closed

          Show
          Aniceto P Madrid added a comment - This issue can no longer be reproducible. I suggest this be closed
          Aniceto P Madrid made changes -
          Assignee SE Support [ support-lep@liferay.com ] Support QA [ support-qa ]
          Michael Saechang made changes -
          Status Open [ 1 ] Closed [ 6 ]
          Assignee Support QA [ support-qa ] Michael Saechang [ michael.saechang ]
          Resolution No Longer Reproducible [ 5 ]
          Fix Version/s 6.2.0 CE M4 [ 13211 ]
          Verified By: aperezymadrid
          Randy Zhu made changes -
          Workflow LPS Workflow [ 500197 ] PUBLIC - LPS Generic Workflow [ 573552 ]
          Randy Zhu made changes -
          Workflow PUBLIC - LPS Generic Workflow [ 573552 ] Copy of PUBLIC - LPS Generic Workflow [ 607862 ]
          Randy Zhu made changes -
          Workflow Copy of PUBLIC - LPS Generic Workflow [ 607862 ] PUBLIC - LPS Generic Workflow [ 639791 ]
          Randy Zhu made changes -
          Workflow PUBLIC - LPS Generic Workflow [ 639791 ] PUBLIC - LPS General Workflow [ 733164 ]
          Randy Zhu made changes -
          Workflow PUBLIC - LPS General Workflow [ 733164 ] PUBLIC - LPS Bugs Workflow [ 829083 ]
          Esther Sanz made changes -
          Component/s Tools > Plugins SDK [ 11769 ]
          Component/s Tools > Plugins SDK > Portlets [ 10301 ]
          Transition Time In Source Status Execution Times Last Executer Last Execution Date
          Open Open Closed Closed
          620d 8h 41m 1 Michael Saechang 08/Apr/13 2:32 PM

            People

            • Votes:
              3 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                2 years, 17 weeks, 1 day ago

                Development

                  Structure Helper Panel