The Holy Java

Building the right thing, building it right, fast

Archive for the ‘Portlets’ Category

Preview of the Portlets in Action book available

Posted by Jakub Holý on November 7, 2009

The book Portlets in Action being written by Ashish Sarin, which I’ve already mentioned and which looks really promising, has been made available via the Manning Early Access Program. As of today there are two chapters available and you can read the first one "Introducing Portals and Portlets" for free.

What I find to be the most attractive features of this book is that it concentrates on the "new" JSR 286 also known as Portlets 2.0 and goes beyond teaching portlets with its intorduction of Spring MVC and Ajax libraries suitable for portlets.

Posted in Portlets | 2 Comments »

The quest for a portal web framework is over and the winner is: Spring Portlet MVC

Posted by Jakub Holý on July 4, 2009

For a long time I’ve been looking for a web framework that would ease the development of web UI in portlets. Pure JSP is too old-fashioned and the abstraction it provides is just too low-level. There are many good web frameworks for standard web applications (JSF/Seam, GWT, Struts 2, Wicket, you name it…) but if they include portlet support than only as an after-thought and it’s usually far behind the quality and features of the standard web framework. Nobody was able to recommend me a decent portlet web framework – until recently.

 First I’ve learned about an upcoming book Portlets in Action (preview) by Ashish Sarin, which teaches not only Portlets 2.0 (JSR 286) but also other must-haves for a real world development like a portlet web framework and Ajax (DWR in this case). You’ve surely already guessed that Ashish uses Spring Portlet MVC, which indicates that it must be indeed good.

Than I’ve been surprised to learn that my good and trustworthy collegue, Vlado, is using Spring Portlet MVC on his project. He had but positive words about the framework: "It’s excellent, I wouldn’t make portlets with anything else. It’s enough lightweight, it helps where it should and doesn’t limit you anyhow."

The only issue is that the current stable release doesn’t support JSR286 yet (events, resource serving…). Fortunately the upcoming release of Spring 3.0 will support it. Spring 3.0 M3 have been released in May 2009 (more about Portlet 2.0 support on M2 release page), RC1 should have been released in June. You can learn about details in the corresponding Jira issue.

Update 2/2010:  Liferay uses quite a lot Struts to build its portlets, for instance when developing a portlet as an EXT plugin (not recommanded), you can only use Struts, so Struts is surely a viable alternative. There is a discussion of Spring vs. Struts at Liferay forums (6/2009).

Resources

Posted in Portlets | 1 Comment »

How I managed to deploy a JSF/Seam portlet to JBoss after all

Posted by Jakub Holý on April 20, 2009

Deploying a custom JSF/Seam portlet to JBoss Portal Server isn’t as easy as you’d expect, either manually or using Eclipse with JBoss Tools. I’ll share with you what I learned about this.

Introduction

See the previous Seam Tutorial 1.1 and 1.2 to learn what SW versions I use, how to configure a server in Eclipse etc. The issues with JBoss Tools, JBoss Portal, and Seam/RichFaces depend pretty much on their respective version and can change significantly even with a minor version change.

Including:

  • jboss-portlet-bridge-1.0.0.B6

In the blog JBoss Portlet support in Eclipse you may learn more about creating portlets for JBoss in Eclipse and issues with various versions of JBoss Tools.

Deploying a portlet via Maven 2

JBoss provides Maven archetypes for creating Seam portlets and also tasks for deploying them to a portal server, either an existing one or a newly downloaded one. This is described in the development guide but not sufficiently.

Note: You need maven 2.0.9 or higher.

  1. run$ mkdir /tmp/jboss; cd /tmp/jboss
  2. run$ mvn archetype:generate
    -DarchetypeGroupId=org.jboss.portletbridge.archetypes
    -DarchetypeArtifactId=seam-basic
    -DarchetypeVersion=1.0.0.B6
    -DgroupId=eu.ibacz.seamtutorial2
    -DartifactId=seamproject
    -DarchetypeRepository=http://repository.jboss.org/maven2/

    (accept all defaults)
  3. cd /tmp/jbossrun/seamproject
  4. edit /tmp/jboss/seamproject/web/pom.xml
    • Running mvn install would fail because of missing org.jboss.portletbridge:portletbridge-api:jar:1.0-SNAPSHOT for  eu.ibacz.seamtutorial2.web:seamproject:war:1.0-SNAPSHOT.
    • => replace <version>${project.version}</version> with <version>${portletbridge.version}</version> for artifactId portletbridge-api in /tmp/jboss/seamproject/web/pom.xml
  5. run$  mvn install
    This will create a WAR package and install it into the local maven repository.
  6. run$ cd /tmp/jboss/seamproject/ear
  7. run$  mvn -Plocal-portal cargo:start
    This uses the Maven plugin cargo to start a local JBoss Portal. It must be run from the ear/ folder because ear/pom.xml defines the necessary settings.
  8. Set the JDK to use if needed – JBoss requires JRE 1.5. and has troubles under 1.6. You may define the JRE to use by adding a property like
    <cargo.java.home>/path/to/jdk1.5.0_17/jre</cargo.java.home>

    to the other cargo properties in ear/pom.xml
    Indication of the problem: an error like below in jboss startup log:
    [INFO] [talledLocalContainer] Caused by: java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage
    – Strangely jboss still reports jre 1.6 after setting this property but the error disappears:
    [INFO] [talledLocalContainer] 10:14:54,415 INFO  [ServerInfo] Java version: 1.6.0_07,Sun Microsystems Inc.

    Output:
    [INFO] [cargo:start]
    [INFO] [talledLocalContainer] Parsed JBoss version = [4.2.3]
    [INFO] [talledLocalContainer] JBoss 4.2.3 starting…

    [INFO] [talledLocalContainer] 10:01:34,211 INFO [Server] JBoss (MX MicroKernel) [4.2.3.GA (build: SVNTag=JBoss_4_2_3_GA date=200807181417)] Started in 2m:34s:75ms

  9. (in new window) run$ mvn cargo:deploy -Plocal-portal
    [INFO] [cargo:deploy]
    [INFO] [talledLocalContainer] Parsed JBoss version = [4.2.3]
    [INFO] [stalledLocalDeployer] Deploying [/POWEROLAP/jboss/seamproject/ear/target/seamproject-1.0-SNAPSHOT.ear] to [/POWEROLAP/jboss/seamproject/ear/target/installs/jboss-portal-2.7.0.GA-bundled/jboss-portal-2.7.0.GA/server/default/deploy]...
    (Some related logs are added also to the window where we started jboss.)
  10. Go to http://localhost:8080/portal You should see a tab called “seamproject” in the portal.

The bug report DOC-13317 describes the shortcomings of the documentation for this.

Manual deployement of a Seam portlet created with Eclipse/JBoss Tools

How to create a Seam portlet in Eclipse with JBoss Tools and deploy it to JBoss Portal.

Create a new Seam portlet project

Note> There are multiple ways to create a Seam Portlet project.

New > Project > Dynamic Web Project >

  1. Page Dynamic Web Project:
    • Target runtime: jboss 4.3.2 portal 2.7.1,
    • Dynamic Web Module version: 2.5
    • Configuration “JBoss Seam Portlet Project v2.0″; if you haven’t it on the selection list, click [Modify…] and select the facets Seam, JBoss Portlets and all under it (JBoss Core Portlet, JBoss JSF Portlet, JBoss Seam Portlet), Java, Dynamic Web Module.
    • Click Next >
  2. Page Web Modules: keep the defaults.
  3. Page JBoss Portlet Capabilities: keep the defaults (Enable implementation library, Libraries provided by server runtime).
  4. Page JSF Capabilities: keep the defaults (Server supplied JSF implementation, …).
  5. Page Seam Facet: set the Seam runtime and Database as we did in the other projects of my Seam/RichFaces tutorials (TODO link).
  6. Page JBoss Portlet Capabilities: Portletbridge Runtime: select e.g. jboss-portal-2.7.1/server/default/deploy/jboss-portal.sar/lib .

Add a portlet to the project

New > Other… > JBoss Tools Web > Portlet > JBoss JSF/Seam Portlet (there is also a plain Java Portlet).

Accept all defaults. This will create a portlet called seamPortlet that will display the page home.xhtrml.

Deploy the portlet

One we have created s Seam portlet we would like to be able to deploy it to JBoss Portal. Here we will learn how to deploy it manually, that means by exporting it from Eclipse as a WAR file and installing that to the server. If you try that you will fail. Below I describe the necessary steps to get the exported WAR working under JBoss.

By comparing the SeamBooking example portlet that you can find in the portlet bridge download package and my Seam portlet exported from Eclipse I’ve discovered the following differences.

  • SeamBooking’s META-INF/ contains a persistence.xml (likely some JPA stuff).
  • SeamBooking’s jboss-portlet.xml defines links to 2 RichFaces JavaScript files and 1 CSS file.
  • SeamBooking’s jboss-object.xml has the property theme.renderSetId=emptyRenderer .
  • My portlet exported from Eclipse contains many libraries in WEB-INF/lib/ but not e.g. any portletbridge stuff.

Deploy the exporeted WAR to JBoss and start it.

Attempt I – failure:

  1. Missing portletbridge class:
    Cause: Unable to find class 'org.jboss.portletbridge.application.PortletViewHandler'

    &l
    t;li>Missing datasource.

Solution:

  1. Copy portletbridge-impl.jar and portletbridge-api.jar to the WAR’s WEB-INF/lib/.
  2. Copy
    /resources/*-ds.xml to deploy/.

Attempt II – failure:

ERROR [LifeCycle] Cannot start objectorg.jboss.portal.portlet.container.PortletInitializationException: The portlet seamPortlet threw a runtime exception during init
Caused by: java.lang.ClassCastException: javax.portlet.faces.GenericFacesPortlet cannot be cast to javax.portlet.Portlet
    at org.jboss.portal.portlet.impl.jsr168.PortletContainerImpl.start(PortletContainerImpl.java:254)

Solution: Remove all portal*, portlet*.jar including portlet-api.jar (contains javax.portlet.Portlet.class), excluding. portletbridge.

Attempt III – portlet running:

No there are no more exceptions and when JBoss Portal starts, you will see there the tab “seamPortlet” with your portlet.

However when you go to the tab to see your portlet there will be another exception:

ERROR [InternalPortletContentProvider] Portlet invoker exception during portlet window renderingorg.jboss.portal.portlet.PortletInvokerException: javax.servlet.ServletException
Caused by: java.lang.NoSuchMethodError: org.ajax4jsf.context.ViewResources.processHeadResources(Ljavax/faces/context/FacesContext;)V

Solution: Replace libs with richfaces-api-3.3.0.GA.jar richfaces-impl-3.3.0.GA.jar richfaces-ui-3.3.0.GA.jar

Attempt VI – everything finally works.

Seam portlet deployment from Eclipse with JBoss Tools

This is something I haven’t managed so far :-(

Posted in Portlets | Tagged: , , , , , , , , , , | 2 Comments »

Developing portlets for Liferay in Eclipse

Posted by Jakub Holý on April 20, 2009

In this blog I’d like to tell you how to use Eclipse with Liferay to develop portlets with the ability to change a class or a JSP in Eclipse and have that immediatelly reflected on the server (hot deployment).

Environment

  • Liferay Portal 5.2.2 running on Tomcat 5.5.27.
  • Eclipse IDE for Java EE Developers, version Ganymede 3.4.1.
  • (optional) Eclipse Maven plugin m2eclipse 0.9.6.

A note about Eclipse and Maven projects

My web project is actually also a Maven project because we use Maven for building our projects. That means that it has a specific directory structure (src/main/webapp, target/classes, etc.) and that it includes a pom.xml that defines its dependencies on other artifacts, usually JAR libraries. Thanks to the m2eclipse plugin, Eclipse is aware of these dependencies and makes them available to the project during development and deployment.

With the m2eclipse plugin you get the nice feature that if your web application project depends on an artifact produced from another Eclipse project then if you change something in this project you depend upon, Eclipse detect it and pushes the change to the web application deployed on a server.

Normally with maven alone you would need to run mvn install or mvn package on the library project and either copy the produced .jar manually to the deployed webapp’s WEB-INF/lib or do a full rebuild (mvn package) and redeploy of the web app.

Preparing the portlet project for hot deployment to Liferay

Normally you deploy a WAR with portlets by putting them in the Liferay’s hot deploy directory (<liferay>/deploy). It notices that, processes the WAR, and deploys it to Tomcat. However since Eclipse knows nothing about Liferay and can only deploy to Tomcat itself in the normal way, that means by copying the exploded WAR to <liferay>/tomcat-5.5.27/webapps/, we need to do the Liferay’s modifications by ourselves and also modify the way that Eclipse does the deployment. Liferay does monitor Tomcat’s webapps/ directory and will detect a change to an application and redeploy it however this deployment doesn’t include all the operations that are performed when deploying via its hot deploy directory.

Configuring Eclipse

1. Define a Server Runtime Environment for Liferay

  1. Window > Preferences > Server > Runtime Environments > Add… .
  2. Select Apache Tomcat 5.5.
  3. For the Tomcat installation directory browse to or type <liferay>/tomcat-5.5.27 (replace <liferay> with you liferay installation directory, of course).
  4. Name it e.g. “Liferay 5.2.2@Tomcat 5.5.27″.

2. Define a Server instance for Liferay

  1. Window > Show View > Other… > Server > Servers.
  2. Right-click somewhere in the view Servers > New > Server:
    • Server type Tomcat v5.5 Server.
    • Server runtime environment: select the one defined in the previous step (Liferay 5.2.2@Tomcat 5.5.27).

3. Adjust the server’s configuration

In the view Servers, double-click on the newly created server, which will open its configuration. Do the following modifications:

  • In Server Locations change “Use workspace metadata” to “Use Tomcat installation”.
    • Notice: If you have any projects deployed to the server, this section is greyed-out and cannot be edited. Remove all projects from the server, publish, perhaps restart and you should be able to modify this settings.
  • In Server Locations change Deploy path from wtpwebapps to webapps. (Maybe this isn’t necessary but I wanted to be sure I won’t create any troubles for the Liferay’s monitoring.)
  • In Timeouts perhaps increase the Start timeout to some period long enough, e.g. 300 s. (My Liferay usually starts in ~ 70s but once it took over 200 s.)
  • During server startup, if you get

    Exception in thread “main” java.lang.OutOfMemoryError: PermGen space

    then click Open launch configuration in the server’s configuration and add something like -XX:MaxPermSize=128m to Arguments > VM arguments.

Now you should be able to run the server, deploy your portlet webapp to it (view Servers > right-clik the server > Add and Remove Projects …) and see your portlets in the Liferay portal (login, Add application > find it under the category you’ve defined in your liferay-display.xml > add it to a page).

When you deployed the application to the server, you should have been able to see in the log (i.e. in the Eclipse’s Console view) that Liferay has detected it and deployed the portlets. There should be a line like

INFO [PortletHotDeployListener:303] 1 portlets for <your webapp’s name> are available for use

telling you that your portlet is deployed and ready to use.

Adjusting the portlet project

When you add you portlet to a portal page, you will be most likely surprised to see there
The requested resource (/example-portlet/MyPortlet/invoke) is not available.
instead of the expected portlet content. (Of course it will differ if your project/webapp context root isn’t example-portlet and the portlet’s name isn’t MyPortlet.)

Google won’t reveal any solution but I’ll will :-). Try to deploy the application first from Eclipse (which you’ve just done) and then in the regular way by exporting it as a WAR file from Eclipse and putting it into <liferay>/deploy/ and waiting for Liferay to pick it up and deploy it to Tomcat. Then compare the two resulting directories from Tomcat’s webapps/ folder. Thus you will learn what you will need to modify. Or simply keep on reading :).

Adjust web.xml

Liferay needs to have a servlet defined for each portlet. The error above (The requested resource (/example-portlet/MyPortlet/invoke) is not available.) indicates that a servlet MyPortlet is missing. So we will add it together with the proper servlet mapping:

web.xml modification:

<servlet>
        <servlet-name>MyPortlet</servlet-name>
        <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
        <init-param>
            <param-name>portlet-class</param-name>
            <param-value>eu.ibacz.example.MyPortlet</param-value> <!--replace with your portlet class -->
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
        ....
    <servlet-mapping>
        <servlet-name>MyPortlet</servlet-name>
        <url-pattern>/MyPortlet/*</url-pattern>
    </servlet-mapping>

Add portlet TLD

We will likely (though I’m not 100% sure about this) need to replicate yet another change done by Liferay and that is adding it’s TLD for portlet 2.0 and a link for it to web.xml. Liferay adds taglibs also for all its other taglibs but I suppose you don’t need them. (I suppose you develop a JSR 286 portlet but you could do the same for a JSR 168 portlet by using its specific uri and tld file.)

1. Copy liferay-portlet.tld to WEB-INF/tld/liferay-portlet.tld. Get it from the Liferay-deployed WAR or find in somewhere under <liferay>.

2. Add a taglib declaration to web.xml:

        <taglib>
            <taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>
            <taglib-location>/WEB-INF/tld/liferay-portlet.tld</taglib-location>
        </taglib>

Adding Liferay libs

You will likely need to add at least the Liferay library
<liferay>/tomcat-6.0.18/webapps/ROOT/WEB-INF/lib/util-taglib.jar
to your projet’s WEB-INF/lib. If you ommit that you may, when accessing the portlet, get for example one of the following errors:

 javax.portlet.PortletException: javax.servlet.ServletException: java.lang.NoClassDefFoundError: com/liferay/taglib/portlet/DefineObjectsTag
JasperException: Impossible de charger ou d'instancier la classe TagExtraInfo: com.liferay.taglib.portlet.ActionURLTei

That’s all, folks!

That’s all! Your portlet should work now (tough Eclipse may require Tomcat restart for that). Enjoy!

About the portlet project

Selected files of the project’s WAR:

  • WEB-INF/
    • lib/
      • util-taglib.jar
    • tld/
      • liferay-portlet.tld
    • classes/
      • eu.ibacz.example.MyPortlet.class
    • liferay-display.xml
    • liferay-plugin-package.properties
    • liferay-portlet.xml
    • portlet.xml
    • web.xml
  • myPortlet_view.jsp

eu/ibacz/example/MyPortlet.java:

package eu.ibacz.example;

import java.io.IOException;
import javax.portlet.*;

public class MyPortlet extends GenericPortlet {
	
	@Override
	protected void doView(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {		

		PortletRequestDispatcher dispatcher = getPortletConfig().getPortletContext().getRequestDispatcher(
				"/myPortlet_view.jsp");
		if (dispatcher != null) {
			//dispatcher.forward(request, response); // this displays an empty page instead of the JSP?!
			dispatcher.include(request, response);	// this works
		} else {
			throw new IllegalStateException("Failed to get a PortletRequestDispatcher, can't forward to the JSP");
		}
	}
}

liferay-display.xml:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE display PUBLIC "-//Liferay//DTD Display 5.2.0//EN" "http://www.liferay.com/dtd/liferay-display_5_2_0.dtd">
<display>
  <category name="My Experiments">
    <portlet id="MyPortlet">My Test Portlet</portlet>
  </category>
</display>

liferay-plugin-package.properties (I suppose this actually isn’t need or could be empty):

portal.dependency.jars=commons-logging.jartags=portlet

liferay-portlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_5_2_0.dtd">
<liferay-portlet-app>
       
    <portlet>
        <portlet-name>MyPortlet</portlet-name>
        <instanceable>true</instanceable>
    </portlet>
    
    <role-mapper>
        <role-name>administrator</role-name>
        <role-link>Administrator</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>guest</role-name>
        <role-link>Guest</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>power-user</role-name>
        <role-link>Power User</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>user</role-name>
        <role-link>User</role-link>
    </role-mapper>
    
</liferay-portlet-app>

portlet.xml:

<?xml version='1.0' encoding='UTF-8' ?>
<portlet-app xmlns='http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd' version='2.0'>    
    
    <portlet>
        <description></description>
        <portlet-name>MyPortlet</portlet-name>
        <display-name>MyPortlet</display-name>
        <portlet-class>eu.ibacz.example.MyPortlet</portlet-class>        
        <expiration-cache>0</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>VIEW</portlet-mode>
        </supports>
        <portlet-info>
            <title>MyPortlet</title>
            <short-title>MyPortlet</short-title>
        </portlet-info>
    </portlet>
    
</portlet-app>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>My Test Portlet Webapp</display-name>
    <description/>
    

    <servlet>
        <servlet-name>JHPokusy</servlet-name>
        <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
        <init-param>
            <param-name>portlet-class</param-name>
            <param-value>eu.ibacz.studna.PokusnyPortlet</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
        
    <servlet-mapping>
        <servlet-name>JHPokusy</servlet-name>
        <url-pattern>/JHPokusy/*</url-pattern>
    </servlet-mapping>
    
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <jsp-config>                
        <taglib>
            <taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>
            <taglib-location>/WEB-INF/tld/liferay-portlet.tld</taglib-location>
        </taglib>
   </jsp-config>

</web-app>

myPortlet_view.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<h1>MyPortlet is alive!</h1>

Known issues

Omission of .properties during deploy

Sometimes Eclipse omits to copy .properties files to the server. I don’t know whether it’s Eclipse problem or my Eclipse Maven plugin problem. I don’t know why because .settings/org.eclipse.wst.common.component does contain <wb-resource deploy-path=”/WEB-INF/classes” source-path=”/src/main/resources”/>. I’ve open the bug report MECLIPSE-556 regarding this.

Enforcing a particular JDK version

If you use the maven enforcer plugin to enforce a particular version of Java, like this:

<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-enforcer-plugin</artifactId>
		<configuration>
				<rules>                                                
						<requireJavaVersion>
								<version>[1.5,1.6)</version>
								<message>...</message>
						</requireJavaVersion>
				</rules>
		</configuration>
		<executions>
				<execution>
						<id>enforce-versions</id>
						<goals>
								<goal>enforce</goal>
						</goals>
				</execution>
		</executions>
</plugin>

then you may have troubles building your Maven project with Eclipse if running Eclipse under another JVM version. For example my default system JVM used also for Eclipse is 1.6 but for a particular project I need 1.5. When you try to build the project, it will fail with

Build errors for jpivot-portlet-liferay-classes; org.apache.maven.lifecycle.LifecycleExecutionException:
 Internal error in the plugin manager executing goal 'org.apache.maven.plugins:maven-enforcer-plugin:1.0-beta-1:enforce':
 Mojo execution failed.

I’ve tried the following to force Maven to use JVM 1.5 for building the project:

  1. Set the JRE System Library in Project – Properties – Java Build Path – Libraries.
  2. Set the Eclipse’s command line option -vm to point to the desired JVM in eclipse.ini:
    -vm /usr/lib/jvm/java-1.5.0-sun
  3. Set JAVA_HOME to point to the desired JVM prior to starting Eclipse:
    bash$ export JAVA_HOME="/usr/lib/jvm/java-1.5.0-sun/jre"bash$ ./eclipse
  4. Setting PATH to point to 1.5 JVM prior to startin Eclipse:
    bash$ export PATH="/usr/lib/jvm/java-1.5.0-sun/bin:$PATH"bash$ ./eclipse

Of those only nr. 4, setting the PATH, had the desired effect of running Eclipse and thus also the Maven build under the required JVM 1.5. The conclusion is that you must run Eclipse using the same JVM you want to use for Maven builds.

There is the bug report MNGECLIPSE-1091 regarding this problem with many votes but no resolution or workaround.

Why not to use m2eclipse

A nice post (6/2009) lists some reasons why not to use m2eclipse for Maven-Eclipse integration:

  1. No real support for separate output folder.
  2. It uses the Maven Embedder, which is not Maven but more of an experiment.
  3. It wants to use the JDK associated with the JRE that launched Eclipse.

According to Brian Fox, the upcoming M2e 0.9.9 should address this issues.

Another reader , Benedikt, recommends solutions:

  1. Of course you can change the output-folder by modifying your pom.xml to have separate output-folders for your class-files.
  2. You can tell the plugin which maven installation it should use and it doesn’t break anything if you do so.
  3. If you don’t use the internal maven builder then maven will use the JRE configured under “Installed JREs”.

So maybe its usable after all? Or you may also give try to Eclipse IAM (former Q4E), the new Maven-Eclipse integration, currently v. 0.1.0. It seems to be yet no as mature as m2eclipse, see a comparison.

Additional notes

You may want to follow the instructions on Liferay site and use Liferay in a development mode by using special portal.properties that prevent some caching etc. (Add -Dexternal-properties=$CATALINA_BASE/webapps/ROOT/WEB-INF/classes/portal-developer.properties to <liferay>/tomcat-5.5.27/bin/catalina.sh.)

You may also want to try to install JBoss Tools into your Eclipse and use its Servers view, which also supports Tomcat and may be better than the standard one.

Another interesting SW – Eclipse Portal Pack for developing JSR168 and JSR286 portlets with Eclipse, currently v2.0M1.

An alternative: the Liferay way

The upcoming book Liferay in Action by R. Sezov describes how to set up portlet development environment for Liferay 6 using either Eclipse or NetBeans in its chapter two. He recommands to create and deploy a portlet using the Ant-based Liferay Plugins SDK and use an IDE only to import and develop the portlet while invoking ant deploy for the deployment. I don’t know wheter that supports hot deployment of only changed files (provided that it matters at all) and of course it has a completely different structer than Maven assumes, complicating if not rendering it impossible to use Maven.

Posted in eclipse, Portlets | Tagged: , , , , | 15 Comments »

Seam Tutorial 1.2: RichFaces and paged table (datascroller)

Posted by Jakub Holý on March 23, 2009

In this two-part tutorial you will
learn how to get started with the development of Seam applications
with RichFaces using Eclipse with JBoss Tools. In the 1st
part
we’ve set up our environment, created, and run an empty shell
Seam application. In this 2nd part we will create a simple
web page with a table presenting data on multiple pages using Ajax (a
RichFaces component) and its model stored as a POJO Component in the
Seam Conversation scope. I assume that you already have some basic
knowledge of Seam and JSF, for instance that you know what a
Component or the Conversation scope are. I’ll present my path to this
goal with all the mistakes so that you too can learn from them.

My aim in this tutorial series is to
create a Seam portlet displaying data in a paged (and ideally also
sortable and filterable, but lets be realistic) table running in the
Liferay portal.

Read the rest of this entry »

Posted in Portlets | Tagged: , , , , , | 4 Comments »

When will we see JSR 286 in JSF portlets?

Posted by Jakub Holý on March 17, 2009

Since June 2008 we have the final release of Portlet 2.0 (JSR 286) specification bringing the long sought after features like inter-portlet communication (IPC – events, shared/public render parameters), support for Ajax (resource request), portlet filters and more. It’s already implemented in the latest versions of leading portals including Liferay 5.0, JBoss 2.7, Websphere 6.1 (though you can still encounter some bugs).

Now we would like to know when the lovers of JSF will be able to profit from these features in their JSF portlets.

Current state

Currently it’s possible to embed a JSF 1.2 application into a JSR 168 portal using a Portlet Bridge 1.0 (JSR 301). This is all still quite new – JSR 301 is only a proposed final draft as of June 8th 2009. So you can expect that it will take time to see also support for JSR 286 (or the upcoming JSF 2.0).

Note: Of course you can run JSF portlet bridge 1.0 applications in JSR 286 compliant portals but won’t have an easy access to the new features.

Future

A specification of  Portlet Bridge 2.0 that would bring JSR 286 to the JSF world is being born but it’s still so young that it even hasn’t a JSR number yet. While creating the specification for Portlet Bridge 1.0 took 2-3 years we may hope that 2.0 could be faster as the foundation is already laid by 1.0 but still it will surely take at least half a year, much more likely a year or more. For the time being the only option is to take any of the open source implementations and try to hack the feature you need.

Update: The JSR for Portlet 2.0 Bridge for JSF 1.2 is #329 (thanks, balz).

Implementations

MyFaces Portlet Bridge 2.0, a reference implementation of the new specification being formed, already has some alpha code. They’re quite ahead of time :-)

According to some posts WebSphere Portal 6.1 implementation of portlet bridge seems to support JSR 286 though it is not yet perfect.

JBoss Portlet Bridge (now 1.0.0 beta 6) and Sun JSF Portlet Bridge (1.2.3, 8/2008) plan this perhaps in their 2.0 versions. We can also see that the authors of ICEFaces plan to incorporate this in v2.0 (currently 1.8.0RC1), but likely all of them depend on the specification coming to some stable state.

But a limited support is already available, for instance you can use public render parameters in JSF Portlet Bridge.

Summary

It will take at least months to have a JSR 286 enabled Portlet Bridge buth work is already under way.

Posted in Portlets | 5 Comments »

Seam Tutorial 1.1: RichFaces and paged table (datascroller)

Posted by Jakub Holý on March 7, 2009

In this two-part tutorial you will
learn how to get started with the development of Seam applications
with RichFaces using Eclipse with JBoss Tools. In the 2nd
part
we will create a simple page with a table presenting data on
multiple pages using Ajax and its model stored as a POJO Component in
the Seam Conversation scope. I assume that you already have some
basic knowledge of Seam and JSF, for instance that you know what a
Component or the Conversation scope are.

My aim in this tutorial series is to
create a Seam portlet displaying data in a paged (and ideally also
sortable and filterable, but let’s be realistic) table running in the
Liferay portal. The tutorial will follow my steps with all the dead ends and mistakes so that you too can learn from them.

Why Seam?

In my opinion, Seam is one of the best application frameworks for
Java web application development. It’s not the best one because none
is and it always depends on the task at hand what solution/tool is the most
suitable one. I like Seam because it integrates so well some of the most
popular and standard or de facto standard technologies (all of them
are optional in a Seam application) including JSF, EJB 3.0, JPA, and
Hibernate. Not only does it integrate them but also fixes their
shortcomings (especially in JSF) and adds invaluable features you’ve
been looking for for ages, like the conversation scope, eventing, or
runtime component injection.

Why RichFaces?

The answer is simple: go to see
the RichFaces demo
:-). RichFaces is a library of good-looking,
dynamic (Ajax) JSF components and support for ajaxifying just about
anything. With RichFaces you can easily create Web 2.0 applications
with a professional look and feel that let users forget that they’re
working in a browser with a remote server. You can use context menus,
modal dialogs, sortable, filterable, and pageable tables, rich text
editor, cool visual effects, and more.

RichFaces isn’t the only such library, another popular one is
ICEfaces, which has been embraced by Sun. But RichFaces is supported
by JBoss and works well with its server, portal, and Seam. Remember I
told you Seam is an integration framework?

Why Liferay portal?

Though developing portlet applications is considerably more
difficult than plain old web applications as has been discussed
recently
and as we will certainly yet see, there are also the
benefits of content integration, unified front-end to applications
etc. that sometimes outweigh the problems.

I use Liferay because that’s the portal chosen (for the majority
that can’t afford WebSphere Portal) by the bright guys in the portal
group of my company, IBA CZ.
And also because, as a user, I find it more appealing than JBoss
Portal.

Environment setup

You will need the software listed below. Make
sure to have the same versions or  unexpected problems may happen (examples
later).

  • JBoss Portal 2.7.1
    (with bundled JBoss AS 4.2.3)

  • JDK 1.5 (mine is jdk1.5.0_17 )

  • Seam 2.0.2 SP1 (I’ve preferred this to the latest 2.1.1 GA as it works better with JBoss Tools)It’s already bundled with RichFaces, no separate download of them needed.

    • Check the unpacked folder – there most interesting things are the documentation example applications.
  • Eclipse Ganymede for Java EE v. 3.4.1 (SR1) though you can prefer to try your luck with the latest one (3.4.2 as of today).
  • JBoss Tools as of 2008-12-19 – Seam Tools and JBoss Tools RichFaces 3.0.0
    CR1-R200, JBossAS Tools 2.0.0 CR1-R200, JBoss Portlet 1.0.0 CR1-R200, plus some others. I’ve installed them via Eclipse Update Manager (Help > Software Updates) from the update site http://download.jboss.org/jbosstools/updates/development/ Today it contains an updated version CR2 from 2009-01-28. You can install an older version after unchecking "Show only the latest versions …"

For the sake of completeness I should say that I’m developing
under Linux, namely Ubuntu 8.04 Hardy.

I won’t describe how to install Eclipse and JBoss Tools, you’ll
surely manage that :-). The other items you can just download and
unpack somewhere. for example to /tmp/tutorial/.

Eclipse preparation

After having installed Eclipse and its JBoss Tools plugins:

  1. Let Eclipse know about the JDK 1.5: Window > Preferences >
    Java > Installed JREs > Add… > Standard VM > enter
    path to the unpacked JDK etc.
    Name it “jholy-jdk1.5.0_17 (sorry, I was lazy to rename mine for this tutorial).

  2. Let Eclipse know about the JBoss server: Window >
    Preferences > Server > Runtime Environments > Add… >
    select JBoss, a division of Red-Hat – JBoss 4.2 runtime, …,
    browse to/enter the directory where you unpacked JBoss to
    (/tmp/tutorial/jboss-portal-2.7.1/), and make sure select the previously defined
    JRE (JDK) 1.5. "jholy-jdk1.5.0_17".
    Name it “JBoss 4.2.3 Runtime and Portal
    2.7.1
    ”.

Creating the project

Create the project: File > New > Project > Seam > Seam
Web Project

  • Project name: seamTutorial1
    Note:
    Seam requires the project name to start with a lower-case letter.

  • Target Runtime: JBoss 4.2.3 Runtime and Portal 2.7.1

  • Dynamic Web Module Version: 2.5

  • Target Server: click New > select JBoss AS 4.2, enter
    Server name JBoss_4.2.3, select the recently defined Server runtime environment
    JBoss 4.2.3 Runtime and Portal 2.7.1, click Next >, enter
    Name JBoss_4.2.3, Next, Finish.

  • Configuration: select Dynamic Web Project with Seam 2.0
    (and not the default 1.2).

Screenshot - NewSeamProject 1 (Seam Web Project)

Click Next, don’t modify anything

Screenshot - NewSeamProject 2 (Web Module)

Click Next, don’t modify anything

Screenshot - NewSeamProject 1 (JSF Capabilities)

Click Next to get to the Seam Facet page:

  • Seam Runtime: click Add…, browse to the directory where you
    unpacked Seam to (/tmp/tutorial/jboss-seam-2.0.2.SP1/), give it the
    name jboss-seam-2.0.2.SP1 and set version to 2.0.

  • Deploy as: WAR

  • Database

    • Database Type: Derby

    • Connection profile: click New… > select Derby, enter
      Name SeamTutorial1Derby, Next >, from Drivers select
      “Derby Embedded JDBC Driver 10.2 Default” (if you haven’t it
      there, download it and add it via the small (+) icon), enter a
      non-existent folder as the Database location (e.g.
      /tmp/tutorial/SeamTutorial1Derby), User name sa, leave the password
      empty

      • Test Connection. This will fail if the database location
        folder already exists otherwise it says Ping succeeded!

      • Finish the connection profile creation.

  • Leave the other fields as they are and click Finish to finish the new Seam project wizard.

Screenshot - NewSeamProject 4 (Seam Facet)

Two new projects are created: seamTutorial1 and
seamTutorial1-test. The project seamTutorial1 contains quite a
handful of files:

Screenshot - Package Explorer view of the project seamTutorial1

Open the Seam perspective: Window > Open > Other… >
Seam
. This gives you some useful views, including Seam Components (shows name, scope) and (for page development) JBoss Tools Palette. I’d recommend you to open also JBoss Server View to view and manage your JBoss and Tomcat servers.

Running the generated application

Attempt 1:

  • Right-click on the file seamTutorial1/WebContent/home.xhtml > Run As > Run on Server > select Choose an
    existing server and select the previously defined JBoss_4.2.3.

  • Click Next, you should see the page Add and Remove Projects
    with the Configured projects
    seamTutorial1/resources/seamTutorial1-ds.xml and seamTutorial1,
    click Finish.

  • There may be the warning “The connection was refused when
    attempting to contact localhost:8080”. That’s nothing to worry
    about, the browser is just faster than the server.

  • A Console view should pop up where you can see the log of the
    starting JBoss application server.

    • If you see there errors similar
      to
      UnsupportedOperationException:
      setProperty must be overridden by all subclasses of
      SOAPMessage.

      then you haven’t been attentive enough and are
      running the server with Java 1.6 instead of 1.5. Either switch to
      1.5 or read the release notes of JBoss to learn how to fix this.

    • You may see there
      IllegalArgumentException:
      Exception setting property org.jboss.seam.core.init.jndiPattern on
      component org.jboss.seam.core.init. Expression @jndiPattern@
      evaluated to null.

      • Seam applications are prepared for
        being deployed by Ant, which would replace the token @jndiPattern@ in
        components.xml with a correct value. Unfortunately this version of
        JBoss Tools forgets to do it so you must do it manually.

      • Replace the token @jndiPattern@
        in components.xml with a valid expression, for example #{ejbName}/local.
        See Seam reference, chapter 26.1.5. Integrating Seam with your
        EJB container
        .
        Or better change the project’s build path to WebContent/WEB-INF/classes to get this token replaced with a valid value automatically, see the update from 2009-03-23 at the end of this post.

Attempt 2:

  • Start the application as before. It may take over 7 minutes,
    get a cup of tee. You might notice in the Console view that Seam
    prints name, scope, and type of each installed component. The
    interesting lines there are:
    INFO
    [Server] JBoss (MX MicroKernel) [4.2.3.GA (build:
    SVNTag=JBoss_4_2_3_GA date=200807181417)] Started in
    4m:45s:459ms

    INFO [TomcatDeployer] deploy,
    ctxPath=/seamTutorial1, warUrl=…
    INFO [ServletContextListener]
    Welcome to Seam 2.0.2.SP1

    INFO [SeamFilter] Initializing
    filter: org.jboss.seam.debug.hotDeployFilter
    (the last line)

  • Enter the address
    http://localhost:8080/seamTutorial1
    to your browser. It may take a couple of minutes to load.

Screenshot -  seamTutorial1's home.xhtml running in Firefox

Request for feedback

If you find anything inaccurate or not enough clear in this tutorial or if you encounter some other problems that you would like to share with others to help them avoid these, please let me know. Make the continuous improvement through collaboration possible :-).

Summary

We have set up a Seam development environment, overcame some
problems, and managed to get a simple application running.

In the next part we will develop our own conversation-scope
Component and a page with a RichFaces paged table.

Update 2009-03-23

Replacing  @jndiPattern@ with a valid value in the correct way

During the first deploy we’ve got the following error:

IllegalArgumentException:
Exception setting property org.jboss.seam.core.init.jndiPattern on
component org.jboss.seam.core.init. Expression @jndiPattern@
evaluated to null.

As Dan Allen has pointed out, the token @jndiPattern@ should be replaced by Seam in runtime using the property jndiPatter from components.properties. And actually this property is defined in the project’s src/main/components.properties as jndiPattern=\#{ejbName}/local (‘\’ tells the properties that the # isn’t a comment start). So why it doesn’t replace the token? It turns out that the project has its compile path set incorrectly and a likely side effect is that this file isn’t deployed to the server.

To fix it, In Project > Properties > Java Build Path > Source change the Default output folder from seamTutorial1/build/classes to seamTutorial1/WebContent/WEB-INF/classes. After a redeployment, everything is suddenly working.

By the way I really recommend you reading Allen’s article about improving Seam application performance.

Posted in Portlets | Tagged: , , , , , | 8 Comments »

Are portlets dead? JSR168 and JSR286 versus reality.

Posted by Jakub Holý on January 24, 2009

Eric Spiegelberg, an experienced JEE and portlet developer, evaluates in his article JSR-286: The Edge of Irrelevance the changes brought to the portlet community by the "new" JSR 286 and comes to the sad conclusion that the portlet technology has missed its chance and is declining in interest and momentum and JSR 286 won’t change that. Only rarely do the benefits of this technology outweigh the additional complexity, restricted programming model, and other drawbacks. He explains his opinions and gives reasons for them pretty well and I can only agree.

Some of the points we can make here are:

  • The specification, when finally released, is already outdated. JSR168 needed nearly two years to reach the final release in Oct 2003, JSR286 released in Jan 2008 over two years. Add the time needed by portal vendors to implement it and to remove initial bugs and when you finally get to use it in production it lags like three years behind the present world. As Eric puts it: "Reading between the lines, this means that the stated primary goal
    of the recently released JSR-286 is to align itself with the latest
    and greatest Enterprise Java technology of 2003.
    "
  • Portlet developers are 2nd class citizens, all the progress goes on in the web application space and they always have to wait for the "goodies" like JSF, Ajax, GWT, and when they finally get them – maybe after a year or years of delay – their integration into portlets/portals is usually at least flawed.
  • There is a portlet specification but no portal specification. If you want to build nontrivial (multi)portlet applications you will usually need to use your vendor’s legacy portal API to do necessary things otherwise not possible, loosing the already uncertain benefit of portability.
  • Portlets are more difficult to learn and develop and a developer is more restricted than in a standalone web application. Eric writes: "Professional hands-on experience along with the above research
    led me to the conclusion that the portal architecture lacks
    enough technical advantages and distinguishing features to warrant
    an increase in acceptance. In practice, few applications can
    constrain themselves to the isolated and disparate functionality of
    portlets, and relinquishing this degree of architectural control is
    unrealistic in enterprise-level software.
    "
  • Interest in portlets is clearly declining. As Eric finds out, "18 out of
    24 (75 percent) organizations that officially supported JSR-168 in
    2003 do not officially support JSR-286 today
    ".

It’s a pity that portals and portlets aren’t easier to use and haven’t made it into the mainstream, the abilities of content aggregation, personalization, uniform security etc. are promising and as we can see in the rise of personal mashups like iGoogle, the fundamental ideas behind portals are still valid and extremely attractive. I hope that some mashup technology will soon provide a viable, light-weight alternative to portals.

For the sake of completness I should say that I’m currently working on "portletization" of an application and that I spent some time on a JSR 168 portlet for WebSphere project.

Posted in Portlets | Comments Off