Affects Version/s: 7.1.1 CE GA2
Fix Version/s: None
This problem manifests itself in the following Portlet 3.0 TCK test failures:
This problem only occurs when Liferay Portal has first started and the user has not signed-in. Therefore, a portlet that manifests the problem (such as the aforementioned tests found in V2DispatcherTests.war) must have been either:
1) Deployed during a previous run and added to a portal page prior to shutdown
2) Deployed after startup, but automatically added to a portal page by an automated process
Once a user has signed-in once, then the problem goes away – even if the user signs out.
When a user hasn't yet signed-in since the portal was started, the underlying HttpSession is an instance of org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionAdaptor.
However, after a user has signed-in, the underlying HttpSession is an instance of org.apache.catalina.session.StandardSessionFacade.
The problem manifests itself when a user hasn't yet signed in because HttpSessionAdaptor.getAttribute(String) prepends the session attribute name with a prefix. More details about the prefix are provided at the bottom of this section, just prior to the "Steps to Reproduce" section.
The Portlet 3.0 TCK V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2 test initially renders on the page with a clickable hyperlink. When the link is clicked, it invokes the following RenderURL:
As shown in the URL, the RenderURL has a private render parameter named qparm2 with value "renderVal2".
Invoking the URL will cause the render(RenderRequest portletReq, RenderResponse portletResp) method to be called.
At line#103, the following code creates a ResourceURL:
The Javadoc for MimeResponse.createResourceURL() states:
If allowed by the cacheability setting, public and private render parameters are added to the URL with their current values.
Since the default cacheability is "cacheLevelPage", the qparam2 private render parameter should be added to the URL. The problem is that it's not being added, which causes V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2 to subsequently fail at line 143. The reason why it fails is because the value of qparm2 should have two values:
- Value #1: "renderVal2" (because of the RenderURL)
- Value #2: "qvalue2" (because of the query-string of the path that was used to create a PortletRequestDispatcher to the servlet.
The problem is that only "qvalue2" is found as a value.
To understand why there is only one value, it is necessary to see how Liferay Portal stores public/private render parameters. When the RenderRequest is created, PortletRequestImpl.init(...) is called which executes the following code on line#757:
This successfully creates an underlying HttpSession attribute with the key "PORTLET_RENDER_PARAMETERS" due to line#146 of RenderParametesPool.java:
Coming back to the original problem – the call to portletResp.createResourceURL() does not create a URL that contains the private render parameter "qvalue2" value. The reason why is because line#1602 of PortletURLImpl.java executes the following code:
And the value of renderParameters is null, rather than a map that contains a map entry with key "qparm2" with value "qvalue2".
The reason why it is null is because the underlying HttpServletRequest is decorated by an instance of org.eclipse.equinox.http.servlet.internal.servlet.HttpSessionAdaptor which attempts to add a prefix to the session attribute name, specifically it tries to get the value for an attribute with name "equinox.http.tck-V2DispatcherTestsPORTLET_RENDER_PARAMETERS_" instead of simply "PORTLET_RENDER_PARAMETERS_"
1. Deploy the attached tck-V2DispatcherTests.war artifact to $LIFERAY_HOME/deploy
2. Add the portlet named "DispatcherTests_SPEC2_19_ForwardServletResource" to a portal page
3. Reload the page
4. Click on the " V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2" hyperlink
The portlet test results indicate "Success" for V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2
The portlet test results indicate "Failure" for V2DispatcherTests_SPEC2_19_ForwardServletResource_dispatch2