Creating hybrid Web-Applications with ZK and Maven

I want to describe the basic steps to create a hybrid Web-Application, thats runnable in a normale Application Server, like Tomcat, and is also deployble to a Portlet Server like Liferay. There are lots of other well documented sources that describe the basic steps on each of those Web-Apps independently, so i dont want to get into too much detail here. I mainly want to describe the essential steps, so your Web-App is deployable in both containers. Im using Liferay 5.2.3, it should also be working in other Portlet-Containers, for example JBoss Portal, but i can’t guarantee it. Finally i want to provide a Maven Archetype for the hybrid Web-Application.

folder layout

First we need some deployment descriptors for our Portlet Application. Basically this has to be only the portlet.xml, Liferay is smart enough to figure out the rest, but since we want the portlet to be good-looking we add some Liferay specific descriptors as well:

portlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app version="1.0"
  xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
                     http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
  <portlet>
    <description xml:lang="EN">ZKHybridPortlet</description>
    <portlet-name>ZKHybridPortlet</portlet-name>
    <display-name xml:lang="EN">ZKPortlet</display-name>
    <portlet-class>org.zkoss.zk.ui.http.DHtmlLayoutPortlet</portlet-class>

    <init-param>
      <name>zk_page</name>
      <value>/index.zul</value>
    </init-param>

    <!-- Notice that expiration-cache must be set to zero to prevent portals from caching the result. -->
    <expiration-cache>0</expiration-cache>

    <supports>
      <mime-type>text/html</mime-type>
      <portlet-mode>view</portlet-mode>
    </supports>
  </portlet>
</portlet-app>

The important part here is the ZK DHtmlLayoutPortlet portlet-class. This extends the GenericPortlet from Javas Portlet-API, and therefore implements the basic Portlet Lifecycle methods. Since we don’t have a common Portlet, we need to tell the Portal were to go, after initializing the Portlet. This is done with the zk_page init-param. As you can see, this portlet currently only supports the view portlet-mode, but you can easily add the help and edit mode with the according parameters in the portlet.xml

When deploying to a Liferay Portal, the most important file is the Liferay specific liferay-plugin-package.properties. Liferay adds several filters to the web.xml when you hot-deploy a war file, which renders the AJAX-ability of your zk portlet useless. To circumvent this behavior, you have to set this property and place the file under \WEB-INF.

liferay-plugin-package.properties

speed-filters-enabled=false

The other files under \WEB-INF\ are just to make Liferay happy, but you could easily skip those. The web.xml declaration is straight forward as well. There is actually only the Servlet declaration important. Look up the other settings at the ZKoss Page or in the archetype ๐Ÿ˜‰

web.xml

<servlet>
  <description>ZK loader for evaluating ZUML pages</description>
  <servlet-name>zkLoader</servlet-name>
  <servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>

  <init-param>
    <param-name>update-uri</param-name>
    <param-value>/zkau</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

The beauty of the ZK hybrid Application is, that those settings don’t interfere with each other. You can define your Web-Application Settings in the web.xml which dont mess up the portlet and vice versa.

An offset nevertheless is, that you cant redirect to other zul-pages with execution.sendRedirect() – this simply would’nt work in a Portlet-Environment. This means, that you have to manipulate the DOM-Tree of the Web-Application with Executions.createComponents() whenever the User wants to navigate to a new Page or updates it partially – which means that you loose your Page-URLs. This is not so important in a Portal, because you never really had page-URLS in the first place, but it might be important to consider in a Web Application.

The maven pom.xml is pretty straight forward aswell, so i don’t want to post it here. Its merely everything you need to get a ZK App up & running and deploy it in a Container. Additionally I added some deploy ant tasks: if you trigger a mvn clean, it will delete the exploded folders in both Tomcat and Liferay plus the tmp and work folders of your Liferay Installation. If you trigger a mvn install, it will copy the built war-file into the Tomcat webapps and Liferay deploy folder. You can replace those ant tasks with mavens cargo plugin, but i liked it that way, plus i wanted to make sure that my Web-App would run in a clean installation.

I provided a very simple zul file (copied from the ZK examples page), so you can see how to build your web-app. The one thing to notice here is, that you need a surrounding window element to avoid namespace clashes, like that:

index.zul

<window border="none" mode="embedded">

Thats all you have to do ๐Ÿ™‚ To get started, you can checkout my Archetype from the google code page and play around a little:

svn co http://hybrid-web-applications.googlecode.com/svn/trunk/archetypes/hybrid-zk-archetype
mvn clean install

After that you can create your own hybrid Web-Application with ZK:

mvn archetype:generate -DarchetypeGroupId=de.fabianmaass.archetypes.hybrid.zk -DarchetypeArtifactId=hybrid-zk-webapp -DarchetypeVersion=1.0-SNAPSHOT

A sidenote: The pom wants to deploy the war files to the liferay and tomcat deploy folder. You have to change the path in the pom file or set a system variable, or else the build will fail.

pom.xml

 <properties>
    <tomcat.folder>${env.TOMCAT_HOME}/webapps</tomcat.folder>
    <liferay.folder>${env.LIFERAY_HOME}/tomcat-6.0.18</liferay.folder>
  </properties>

sources:
http://devenphillips.blogspot.com/2009/04/developing-liferay-portlets-with-zk.html
http://docs.zkoss.org/wiki/Portal_integration

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

4 Comments »

 
  • jensse says:

    Hi,

    Thanks, your article eventually provided the last mile. In getting zk up and running.

    -js

  • Caio Formiga says:

    First of all thank you by the initiative.

    I`m having problem to use you archetype, cause I don`t really know how to install it.

    After add url from google code repository to Eclipse SVN perspective, I did a checkout from the project hybrid-icefaces-archetype to my Workspace folder.

    Now, what should I do to install that archetype to my MAven2 repository.

  • fabian says:

    hey caio,

    the archetype is just a project template for future projects, not a development project itself. you have to check out the source somewhere (please not in your workspace environment) and run “mvn install” in the archetype folder to deploy it to your maven repository. after that you can go back to the root of your workspace folder and run the maven commands given in the post..

    good luck ๐Ÿ™‚

  • Amarish says:

    Hi there,

    This seems to work, but I’m having trouble with the datebox widget. When you choose a date in the calendar popup it doesn’t change the text field.

    Any ideas?