0

Liferay 6.1 + JBoss 7.1 + ZK 6 : Issue with the way RenderRequest are wrapped

asked 2012-08-14 03:28:13 +0800

jezelinside gravatar image jezelinside
9

Hi all !

I'm currently working on an integration between Liferay, JBoss and ZK. We ran into some problems with complex UI. Here's a small summary of my analysis :

1. URLEncoder issue

If we use directives such as <style src="./css/custom.css" /> (especially URLs starting with "./"), Liferay raises an exception complaining that the URL is not an absolute one :

 13:56:15,329 GRAVE [org.zkoss] (http--0.0.0.0-8080-2) >>java.lang.IllegalArgumentException: URL path must start with a '/' or include '://'
>>	at com.liferay.portlet.PortletResponseImpl.encodeURL(PortletResponseImpl.java:410)
>>	at org.zkoss.web.portlet.RenderHttpServletResponse.encodeURL(RenderHttpServletResponse.java:118)
>>	at org.zkoss.web.servlet.http.Encodes.encodeURL0(Encodes.java:513)
>>	at org.zkoss.web.servlet.http.Encodes.access$000(Encodes.java:47)
>>	at org.zkoss.web.servlet.http.Encodes$1.encodeURL(Encodes.java:429)
>>	at org.zkoss.web.servlet.http.Encodes.encodeURL(Encodes.java:402)

This may be avoided by using full or absolute URLs but it's a bit confusing to have different behaviours between servlet and portlet modes. Anyway, I don't know if it should be considered a ZK or a Liferay issue but I think URLEncoder should at least handle such errors if possible.

2. RenderHttpServletRequest wrapping

ZK wraps RenderRequests to org.zkoss.web.portlet.RenderHttpServletRequest. It may cause exceptions that go like this :

 13:56:15,342 ERROR [com.liferay.portal.kernel.servlet.PortletServlet] (http--0.0.0.0-8080-2) javax.portlet.PortletException: javax.servlet.ServletException: Original SevletRequest or wrapped original ServletRequest not passed to RequestDispatcher in violation of SRV.8.2 and SRV.14.2.5.1: javax.portlet.PortletException: javax.servlet.ServletException: Original SevletRequest or wrapped original ServletRequest not passed to RequestDispatcher in violation of SRV.8.2 and SRV.14.2.5.1
>>	at org.zkoss.web.portlet.ServletPortletDispatcher.include(ServletPortletDispatcher.java:57) [zweb-6.0.0.jar:]
>>	at org.zkoss.web.portlet.Portlets.include(Portlets.java:72) [zweb-6.0.0.jar:]
>>	at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.handleError(DHtmlLayoutPortlet.java:335) [zk-6.0.0.jar:6.0.0]
>>	at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.doView(DHtmlLayoutPortlet.java:146) [zk-6.0.0.jar:6.0.0]

To avoid this, I tried first to tell JBoss not to strictly test HttpServletRequest's type by setting system property "-Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=false".
This leads to another exception wich is shown below :

 14:16:58,743 ERROR [portal-web.docroot.html.portal.render_portlet_jsp] (http--0.0.0.0-8080-2) java.lang.ClassCastException: org.zkoss.web.portlet.RenderHttpServletRequest cannot be cast to javax.servlet.ServletRequestWrapper
>>	at org.apache.catalina.core.ApplicationFilterFactory.createFilterChain(ApplicationFilterFactory.java:164)
>>	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:827)
>>	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:720)
>>	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:657)
>>	at org.zkoss.web.portlet.ServletPortletDispatcher.include(ServletPortletDispatcher.java:51)
>>	at org.zkoss.web.portlet.Portlets.include(Portlets.java:72)
>>	at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.handleError(DHtmlLayoutPortlet.java:335)
>>	at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.doView(DHtmlLayoutPortlet.java:146)

As an alternative, I rewrote org.zkoss.web.portlet.RenderHttpServletRequest to use standard javax.servlet.http.HttpServletRequestWrapper. Here's my code :

/**
 * A facade of RenderRequest that implements HttpServletRespose.
 * 
 * @author tomyeh
 */
public class RenderHttpServletRequest implements HttpServletRequest {
	private final RenderRequest _req;
	private final HttpServletRequest _hreq;
	private String _enc = "UTF-8";
	private final Map<String, String> _attrs = new HashMap<String, String>(8);

	public static HttpServletRequest getInstance(RenderRequest req) {
		final HttpServletRequest res;

		if (req instanceof HttpServletRequest) {
			res = (HttpServletRequest) req;
		}
		else {
			res = new RenderHttpServletRequest2(req);
		}

		// wraps HttpServletRequest to prevent further type checks :
		return new HttpServletRequestWrapper(res);
	}

	... code unchanged after that ...
}

This works great but I cannot forecast potential side effects of such a modification. Would you mind considering casting a glance at these issues and properly correcting them ?

Many thanks in advance and keep doing such a great job with ZK.
Best regards,

Julien.

delete flag offensive retag edit

2 Replies

Sort by ยป oldest newest

answered 2012-10-08 02:42:46 +0800

neillee gravatar image neillee flag of Taiwan
1692 1 5
https://plus.google.com/u...

Hi all,

Issue #1 occurs since Portlet specification requires absolute path. If you are migrating existing zk applications that included relative path to portlets, you can refer to an workaround posted here.

Issue #2 occurs due to requirement of RequestDispatcher stated in Servlet 2.5 specification. This issue is fixed and will be included in the future releases of ZK.

Neil Lee, Engineer
Potix Corporation

link publish delete flag offensive edit

answered 2012-10-11 00:52:59 +0800

jezelinside gravatar image jezelinside
9

Hi !

Many thanks for your answers and quick fix-up.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
2 followers

RSS

Stats

Asked: 2012-08-14 03:28:13 +0800

Seen: 466 times

Last updated: Oct 11 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More