Tuesday, February 19, 2008

Struts 2 Portlet in JBoss Portal

I have been asked if Struts 2 portlets can be deployed in JBoss Portal, and if yes, how to deploy Struts 2 portlets to JBoss Portal.

The answer to the first question is of course yes. Since Struts 2 Portlet is a JSR168 framework, it can be deployed to any portlet container supporting the JSR168 standard, including JBoss Portal.

To answer the second question, I had to browse through the JBoss Portal reference guide, and found that you have to write two custom deployment descriptors.

For the Struts 2 sample portlet application, I added the following:

portlet-instances.xml


<?xml version="1.0" standalone="yes"?>
<!DOCTYPE deployments PUBLIC
"-//JBoss Portal//DTD Portlet Instances 2.6//EN"
"http://www.jboss.org/portal/dtd/portlet-instances_2_6.dtd">
<deployments>
<deployment>
<instance>
<instance-id>StrutsPortletInstance</instance-id>
<portlet-ref>StrutsPortlet</portlet-ref>
</instance>
</deployment>
</deployments>


struts2-portlet-object.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE deployments PUBLIC
"-//JBoss Portal//DTD Portal Object 2.6//EN"
"http://www.jboss.org/portal/dtd/portal-object_2_6.dtd">
<deployments>
<deployment>
<parent-ref>default.default</parent-ref>
<if-exists>overwrite</if-exists>
<window>
<window-name>StrutsPortletWindow</window-name>
<instance-ref>StrutsPortletInstance</instance-ref>
<region>center</region>
<height>1</height>
</window>
</deployment>
</deployments>


I added both files to the WEB-INF folder of the application.

With both files added, put the war file in the deploy folder of your server, and your portlet should appear on the default page of the portal.

Consult the documentation for a description of these files, and the relations between the names and ids in them.

I would rather not have to specify the instances, page and placement of the portlet in a descriptor in the portlet application itself, but that is how it was described in the documentation.

Update:

It appears that these descriptors are indeed optional. You can deploy a plain Struts 2 Portlet (or any JSR168 portlet for that matter) and do all the required steps in the portal administration.

Monday, February 11, 2008

Struts 2 Portlet in WebSphere 5.1

At work I recently wanted to build a Struts 2 Portlet to see if I could deploy it in WebSphere Portal 5.1. As you know, Struts 2 requires Java 5 to run, and as you might also know, WebSphere Portal 5.1 only runs Java 1.4. Retrotranslator to the rescue! I added the retrotranslator-maven-plugin from the Codehaus Mojo project, and set it up to run the translate-war goal:


<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>retrotranslator-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<goals>
<goal>translate-war</goal>
</goals>
<configuration>
<classifier>jdk1.4</classifier>
<attach>true</attach>
<advanced>true</advanced>
</configuration>
</execution>
</executions>
</plugin>
</build>


I also had to include a couple of new dependencies introduced by Retrotranslator:


<dependencies>
<dependency>
<groupId>backport-util-concurrent</groupId>
<artifactId>backport-util-concurrent</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>net.sf.retrotranslator</groupId>
<artifactId>retrotranslator-runtime</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>


I had to use the 1.0-alpha-2 version of the plugin, otherwise I got an obscure java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean failure...

Unfortunately, that was not quite enough. When running the portlet, I would get an exception about a missing javax.xml.namespace.NamespaceContext class which XWork aparently needs. It appears that this class is included in the Java 5 libraries, but not with Java 1.4. I found it in the jaxp-api.jar in the Sun Java Web Services Developer Pack 2.0. I placed this jar in the %WAS_HOME%/java/jre/lib/ext folder (I tried putting it in the web application, but that didn't work... Classloading in JEE application servers has always been fun...). I also had to exclude any web application dependencies that included Xerces, Xalan or xml-apis.

No guarantees that this works for you though. But I guess as long as you don't break any of the limitations retrotranslator has, you'll be fine.