A brief introduction to Geronimo and Pluto
Apache Geronimo is the new kid on the Java™ Platform, Enterprise Edition (Java EE) server block (version 1.0 was released in January 2006). It's a powerful combination of several other projects, including OpenEJB, Axis, Jetty, Tomcat, ActiveMQ, and ServiceMix. Geronimo is making headlines these days, because it's a different kind of Java 2 Platform, Enterprise Edition (J2EE)-certified server. It's built from the ground up using a dependency injection container. Geronimo also provides fine-grained control over class loaders, allowing you to specify parent-child relationships instead of just dropping all your classes inside a shared lib directory and hoping for the best.
Apache Pluto is the reference implementation for the Portlet specification. It isn't a full-fledged portal server itself. Rather, Pluto is a lightweight portlet container suitable either for embedding inside a full-blown portal server or testing portlets. It's currently used inside several open source portal servers, such as Apache Jetspeed 2, uPortal, and Jahia. Currently, Pluto supports version 1.0 of the Portlet specification (JSR 168); version 2.0 of the specification (JSR 286) is currently under development.
If you're developing portlets or portal servers with Pluto, it makes sense to want to use it with Geronimo. This is especially true if the portal or portlet uses Geronimo-specific features, such as GBeans. The Pluto Web site doesn't explain how to install Pluto on Geronimo, but doing so is possible with a bit of tweaking.
Installing Geronimo is simple: Just download the Jetty-Geronimo bundle (see Resources for a link) from the Geronimo Web site, and unpack it into the GERONIMO_HOME directory. Like Apache Tomcat, you can start the server with the startup script (or batch file) located in the GERONIMO_HOME/bin directory.
Note: This article uses Geronimo 2.0-M2 with Jetty. These steps have not been tested with other versions or with the Tomcat-Geronimo bundle.
Download the Pluto 1.1 bundle from the Pluto site (see Resources for a link), and unpack it into the PLUTO_HOME directory. The bundle is a binary distribution of the Pluto container bundled with Tomcat, so you need to do a little extra work to get it to run on Geronimo.
Note: This article uses Pluto 1.1. These steps have not been tested with previous versions.
Add libraries to the repository
Pluto requires that you place a few JAR files in a shared location so that they can be used by portlet applications and the portal driver itself. As of version 1.1, Geronimo supports a shared library directory. However, creating explicit dependencies is a superior option, because you have more fine-grained control.
To define a dependency on a library, the library must be available in the Geronimo repository. All the Pluto dependencies are in the PLUTO_HOME/shared/lib directory. However, because Geronimo already has some of these libraries installed, you only need to add a few of them to the repository:
- pluto-container-1.1.0.jar
- pluto-descriptor-api-1.1.0.jar
- pluto-descriptor-impl-1.1.0.jar
- pluto-taglib-1.1.0.jar
It's easy to add a new library to the repository through the friendly Geronimo admin console, as shown in Figure 1. Add each of the above libraries through the console, and make sure that each one is in the group org.apache.pluto.
Figure 1. Adding a library to the Geronimo repository
Write the Geronimo deployment plan
The next step is to write a Geronimo deployment plan for the Pluto portal driver, which is the Web application used to run portlets. Plans are XML documents that describe additional Geronimo-specific properties; they replace Java EE deployment descriptors.
The Pluto portal driver resides in the PLUTO_HOME/webapps/pluto directory. Create
a new file in the WEB-INF directory called geronimo-web.xml (this is the
standard name for Geronimo Web deployment plans). In this file, you specify the
dependencies that the Pluto portal driver requires as well as its context path.
First, declare the moduleId, as shown in Listing 1.
Listing 1. Defining the module information for the Pluto portal driver
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<environment>
<moduleId>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto</artifactId>
<version>1.1.0</version>
<type>war</type>
</moduleId>
</environment>
</web-app>
|
This snippet declares a module called pluto in the
group org.apache.pluto. Because you're not using the
shared lib directory, the plan must also declare the dependencies, as shown in
Listing 2.
Listing 2. Declaring the Pluto shared libraries as dependencies
<environment>
...
<dependencies>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto-container</artifactId>
<version>1.1.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto-descriptor-api</artifactId>
<version>1.1.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto-descriptor-impl</artifactId>
<version>1.1.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto-taglib</artifactId>
<version>1.1.0</version>
<type>jar</type>
</dependency>
</dependencies>
...
</environment>
|
This snippet includes all the libraries you added to the Geronimo repository. However, the Pluto portal driver requires a few other libraries that are already installed in the repository, as shown in Listing 3.
Listing 3. Declaring other dependencies
<dependencies>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.8.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>castor</groupId>
<artifactId>castor</artifactId>
<version>0.9.5.3</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>portlet-api</groupId>
<artifactId>portlet-api</artifactId>
<version>1.0</version>
<type>jar</type>
</dependency>
...
</dependencies>
|
These libraries ship with Geronimo, so there's no need to add them to the repository before declaring them as dependencies.
As mentioned earlier, Geronimo is a combination of quite a few open source libraries. In addition to larger components, such as OpenEJB, it uses the Spring Framework, and the administration console even uses an older version of Pluto. To install the Pluto 1.1 portal driver, the Web application must ignore any other Pluto or Spring libraries loaded by the server. Fortunately, you can tell Geronimo to ignore those classes to avoid any confusion, as shown in Listing 4.
Listing 4. Declaring hidden classes
<environment>
...
<hidden-classes>
<filter>org.apache.pluto</filter>
<filter>org.springframework</filter>
</hidden-classes>
</environment>
|
Next, you must specify Pluto's context root, as shown in Listing 5.
Listing 5. Specifying the context root
<web-app>
...
<context-root>/pluto</context-root>
...
</webapp>
|
You're almost finished with the plan, but there's still the "little" issue of security.
The pluto portal driver uses Java EE security roles, so you must map Geronimo roles to the roles defined in the portal driver's web.xml file. The easiest way to get started is to use Geronimo's default security realm, geronimo-admin. All that's necessary is to map the default admin role to the pluto role that the portal driver uses, as shown in Listing 6.
Listing 6. Setting up security role mappings
<web-app>
...
<security-realm-name>geronimo-admin</security-realm-name>
<security>
<default-principal realm-name="geronimo-admin">
<principal name="anonymous"
class="org.apache.geronimo.security.realm.
providers.GeronimoUserPrincipal"/>
</default-principal>
<role-mappings>
<role role-name="pluto">
<realm realm-name="geronimo-admin">
<principal name="system"
class="org.apache.geronimo.security.realm.
providers.GeronimoUserPrincipal"/>
</realm>
</role>
</role-mappings>
</security>
</web-app>
|
You can see that you've defined a default anonymous role and mapped the pluto
role to the user name system, which is the default
administrator account.
The plan is now complete. The entire file is available for download from the Download section.
The final step is to modify the castor.properties file, which is used by Castor,
an open source data-binding framework that both Geronimo and Pluto use. The file
resides in the PLUTO_HOME/webapps/pluto/WEB-INF/classes directory. Open the file,
and disable the parser.validation and
indent properties. Listing 7 shows the modified file.
Listing 7. Modified castor.properties file
org.exolab.castor.parser.validation=false
org.exolab.castor.parser.namespaces=false
org.exolab.castor.indent=false
org.exolab.castor.debug=false
|
That's it for the configuration. Now it's time to publish Pluto into your Geronimo instance.
Package and deploy the .war file
Now that you've completed the configuration changes, you must package the PLUTO_HOME/webapps/pluto directory into a WAR file named pluto-portal-1.1.0.war.
After you've created the .war file, you can easily deploy it using the Deploy New option in the Geronimo administration tool, as shown in Figure 2. (Don't forget to start Geronimo with the startup script.) When the application is deployed, you should be able to access it at http://localhost:8080/pluto/ (shown in Figure 3).
Figure 2. Deploying the Pluto portal driver in Geronimo
Figure 3. Pluto login screen running in Geronimo
To run the Pluto portal driver successfully, you must also install the Pluto TestSuite, which has default portlets that verify that the portal driver is working correctly. Installing the TestSuite is similar to installing the portal driver: You create a deployment plan, package a WAR file, and deploy it.
Write the Geronimo deployment plan
Because you've already added all the shared libraries, you can skip ahead to the deployment plan. Start with Listing 8, which shows the module declaration for the Pluto TestSuite.
Listing 8. Module declaration for the TestSuite
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<environment>
<moduleId>
<groupId>org.apache.pluto</groupId>
<artifactId>testsuite</artifactId>
<version>1.1.0</version>
<type>war</type>
</moduleId>
...
</environment>
...
</web-app>
|
Here you've defined a module called testsuite in the
group org.apache.pluto. TestSuite is a portlet
application, which means that it depends on Pluto-related libraries to run.
Instead of defining several explicit dependencies, you can simply tell Geronimo
that TestSuite depends on the Pluto WAR file, as shown in Listing 9.
Listing 9. Declaring a dependency on the Pluto portal driver
<environment>
...
<dependencies>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto</artifactId>
<version>1.1.0</version>
<type>war</type>
<import>classes</import>
</dependency>
...
</dependencies>
...
</environment>
|
The <import> element tells the server to
load the parent classes (in this case, the Pluto portal driver and its
dependencies) first.
To ensure that the Web application class loader picks up the portlet TLD files,
you must also declare the portlet taglib directly, as
shown in Listing 10.
Listing 10. Declaring a dependency on the Pluto taglib
<dependencies>
...
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto-taglib</artifactId>
<version>1.1.0 </version>
<type>jar</type>
</dependency>
</dependencies>
|
Finally, use the <inverse-classloading/>
element, which tells Geronimo to load classes within the Web application's
CLASSPATH (WEB-INF/lib and WEB-INF/classes) first (see Listing 11).
Listing 11. Setting inverse class loading
<environment>
...
<inverse-classloading/>
</environment>
|
The rest of the plan is similar to the one for the Pluto portal driver, except that TestSuite expects a role named tomcat instead of pluto.
There's one extra step. In earlier versions of the Pluto 1.1 distribution, the web.xml file in the PLUTO_HOME/testsuite/WEB-INF directory is missing the Document Type Definition (DTD) declaration, which Geronimo isn't happy about. You must add this declaration to the top right after the XML declaration, as shown in Listing 12.
Listing 12. Add the DTD declaration to web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
|
Later versions of Pluto may have solved this issue. (It has been filed in their issue tracker.)
Package and deploy the WAR file
The final step is packaging and deploying TestSuite. Package the PLUTO_HOME/webapps/testsuite directory into a WAR file named pluto-testsuite-1.1.0.war. Just as with the Pluto portal driver, you can easily deploy TestSuite using the Deploy New option in the Geronimo administration tool. After the application has been deployed, you should be able to access it directly at http://localhost:8080/testsuite/. You should see the text "Hello world!" (see Figure 4).
Figure 4. Output of the Pluto TestSuite (running as a Web application)
Now that TestSuite works independently, it's time to see it inside Pluto. Return to the Pluto portal driver at http://localhost:8080/pluto/, and log in using the Geronimo system user account. You should see the portal driver running with Test Portlet 1 and Test Portlet 2 from TestSuite, as shown in Figure 5.
Figure 5. Pluto portal driver running with the TestSuite portlets
Congratulations! You've successfully installed Pluto on Geronimo. Hopefully, you'll see some of these steps automated through Ant tasks in the future. Now let's walk through the process of writing and deploying a simple portlet.
Writing a portlet is similar to writing a servlet. If your integrated development environment (IDE) supports portlet development, create a new portlet project; otherwise, a normal Web application project will be sufficient. In this example, you'll use the raw Portlet application program interface (API), but in a real application, you should use a Web framework such as JavaServer Faces (JSF), Struts, or Spring MVC. (For a complete Eclipse project with this example, see the Download section.)
The primary difference between writing a portlet and writing a servlet is that
there are methods for specific portlet modes (such as help, edit, or view) and
handling portlet actions. This simple Hello, World! portlet should subclass
the GenericPortlet class and implement the
doHelp(), doEdit(), and
doView() methods, as shown in Listing 13.
Listing 13. Hello world! portlet
package com.virtua.examples.portlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
public class HelloWorldPortlet extends GenericPortlet
{
protected void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
PrintWriter writer = new PrintWriter(response.getWriter());
writer.println("You're now in Edit mode.");
}
protected void doHelp(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
PrintWriter writer = new PrintWriter(response.getWriter());
writer.println("You're now in Help mode.");
}
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
PrintWriter writer = new PrintWriter(response.getWriter());
writer.println("Hello world! You're in View mode.");
}
}
|
This is a simple read-only portlet that displays a different string of text depending on the portlet's current mode. There are two things to note:
- Before the portlet outputs any data, you must set the content type.
- The portlet imports classes from the javax.portlet package. To access this
package, you must include
portlet-api-1.0.jarin your build path; you can get this file from PLUTO_HOME/shared/lib.
Write the deployment descriptors
After you've written the Hello, World! portlet, you must write three short deployment descriptors: web.xml, portlet.xml, and geronimo-web.xml. (Some of these may have been generated by your IDE.) All these files should be in the portlet application's WEB-INF directory.
The first file, web.xml, simply requires a reference to Pluto's
PortletServlet, which helps the portal driver serve
portlets. (This class is different for most portal servers.) The file is shown in
Listing 14.
Listing 14. Hello World! portlet deployment descriptor
<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>HelloWorldPortlet</display-name>
<servlet>
<servlet-name>HelloWorldPortlet</servlet-name>
<servlet-class>
org.apache.pluto.core.PortletServlet
</servlet-class>
<init-param>
<param-name>portlet-name</param-name>
<param-value>HelloWorldPortlet</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldPortlet</servlet-name>
<url-pattern>/PlutoInvoker/HelloWorldPortlet</url-pattern>
</servlet-mapping>
</web-app>
|
As you can see, the deployment descriptor specifies a single servlet that uses
the class org.apache.pluto.core.PortletServlet and is
configured to load the HelloWorldPortlet. Also, note
that the servlet is mapped to a URL pattern that begins with
/PlutoInvoker/, which is required for Pluto.
The portlet application descriptor, portlet.xml, provides a few portlet-specific details, as shown in Listing 15.
Listing 15. Hello, World! portlet descriptor
<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0"
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>Hello, world! portlet</description>
<portlet-name>HelloWorldPortlet</portlet-name>
<display-name>HelloWorldPortlet</display-name>
<portlet-class>
com.virtua.examples.portlet.HelloWorldPortlet
</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>HELP</portlet-mode>
</supports>
<portlet-info>
<title>Hello, Pluto on Geronimo!</title>
</portlet-info>
</portlet>
</portlet-app>
|
Here, the descriptor defines your HelloWorldPortlet,
providing a description, display name, class name, and title. Portlet.xml also
specifies the portlet modes that this portlet supports, which in this case are
VIEW, EDIT, and
HELP.
Write the Geronimo deployment plan
Just as with the previous Web applications, the Geronimo deployment plan resides in WEB-INF/geronimo-web.xml. This file, shown in Listing 16, is similar to the TestSuite plan but doesn't require security roles.
Listing 16. Hello, world! portlet deployment plan
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<environment>
<moduleId>
<groupId>com.virtua.examples.portlet</groupId>
<artifactId>HelloWorldPortlet</artifactId>
<version>1.0</version>
<type>war</type>
</moduleId>
<dependencies>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto</artifactId>
<version>1.1.0</version>
<type>war</type>
<import>classes</import>
</dependency>
<dependency>
<groupId>org.apache.pluto</groupId>
<artifactId>pluto-taglib</artifactId>
<version>1.1.0</version>
<type>jar</type>
</dependency>
</dependencies>
</environment>
<context-root>/HelloWorldPortlet</context-root>
</web-app>
|
As you can see, you define a module for the portlet application as well as
dependencies on the Pluto portal driver and the
pluto-taglib library. Note that you don't include the
<inverse-classloading/> element this
time, because it's not necessary.
Now that all the artifacts are ready, let's build this thing!
Building the portlet application should be a simple process within your IDE; remember, the only dependency is portlet-api-1.0.jar. You must, however, make sure that this .jar file is not deployed with the .war file, because it's already in the Geronimo repository. Packaging is simple, too: The entire Web directory should be packaged as a WAR file named HelloWorldPortlet.war. (If you want to save time, the Eclipse project includes an Ant script; see the Download section).
Now that the .war file is complete, you can use the Geronimo console to deploy it, just as you did for the Pluto portal driver and TestSuite applications. Alternatively, you can use Geronimo's hot deployment mechanism and place the .war file in the GERONIMO_HOME/deploy directory.
After the HelloWorldPortlet has been deployed, you can add it to a Pluto portal driver page through the Pluto Admin portlet:
- Log in to Pluto as normal, and select the Pluto Admin option from the Navigation menu.
- Inside the Admin portlet, select the Secondary Page, then select the
HelloWorldPortlet portlet application, as shown in Figure 6.
Figure 6. Adding the HelloWorldPortlet to the Pluto portal driver
- Click Add Portlet to complete the operation.
Note: In versions 1.1.3 and earlier of Pluto, the Portlet Page Administrator doesn’t save its changes when either the application server or Pluto is shut down. To persist the changes between restarts, you must manually edit pluto-portal-driver-config.xml (located in Pluto's WEB-INF). This has been fixed in the source tree and will be available as part of Pluto 1.1.4.
Congratulations! You've deployed your first custom portlet on Geronimo. You can view the portlet by selecting the Secondary Page from the Navigation menu. HelloWorldPortlet should be displayed below the two test portlets. Figure 7 shows this display with the two test portlets minimized.
Figure 7. The HelloWorldPortlet
Apache Geronimo includes many unique and powerful features, and Apache Pluto is the reference implementation for the Portlet API. If you use Geronimo and want to test your portlets on Pluto, installing Pluto on Geronimo is a logical thing to do.
The official Pluto distribution comes with Tomcat, but with a bit of tweaking, you can deploy the Pluto portal driver on Geronimo. And when you've gotten that far, writing and deploying a custom portlet is fairly straightforward. With a bit of effort, you can use two of Apache's most promising projects together in perfect harmony.
| Description | Name | Size | Download method |
|---|---|---|---|
| Eclipse 3.2 workspace and deployment plans | pluto-geronimo-example.zip | 3MB | HTTP |
Information about download methods
Learn
- Rakesh Midha's article,
"Develop and deploy Apache Pluto portal applications on Apache Geronimo"
(developerWorks, April 2007) guides you through a different sample application
that allows users to purchase tickets and gives you more practice developing
portal applications on Geronimo.
- For more information about dependency injection,
see Neal Ford's series,
Dependency
injection in Apache Geronimo"
(developerWorks, February 2006).
- Visit the
JSR 168 page to learn more about
the Portlet specification.
- Check out the developerWorks Apache Geronimo project area for articles, tutorials, and other resources to help you get started developing with Geronimo today.
- Find helpful resources for beginners and experienced
users at the Get started now with Apache Geronimo section of developerWorks.
- Check out the IBM® Support for Apache Geronimo offering, which lets you develop Geronimo applications backed by world-class IBM support.
- Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
- Stay current with developerWorks technical events and webcasts.
- Browse all the Apache articles and free Apache tutorials available in the developerWorks Open source zone.
- Browse for books on these and other technical topics at the Safari bookstore.
Get products and technologies
- Visit the
official Geronimo site to download the
latest version and learn more about the product.
- Download the
Jetty-Geronimo bundle to
run the example in this article.
- Visit the
official Pluto site to download the
latest version and learn more about the project.
- Check out the
official Jetspeed site to
download the latest version and learn more about the project.
- Download
Jahia, and learn more about the project.
- Get
uPortal, and learn more about the project.
- Download the
latest version of the Eclipse SDK.
- Download your free copy of IBM WebSphere® Application Server Community Edition — a lightweight J2EE application server built on Apache Geronimo open source technology that is designed to help you accelerate your development and deployment efforts.
- Innovate your next open source development project with IBM trial software, available for download or on DVD.
Discuss
- Stay up to date on Geronimo developments at the Apache Geronimo blog.
- Get involved in the developerWorks community by participating in developerWorks blogs.

Kito D. Mann is editor-in-chief of JSF Central and the author of JavaServer Faces in Action (Manning, 2005). He's a member of several Java Community Process expert groups (including JSF and Portlets) and an internationally recognized speaker. Kito is currently the principal consultant at Virtua, Inc., specializing in enterprise application architecture, training, development, mentoring, and JSF product strategy. He holds a Bachelor of Arts degree in computer science from Johns Hopkins University.
Comments (Undergoing maintenance)





