Level: Intermediate Kito D. Mann (kmann@virtua.com), Principal Consultant, Virtua, Inc.
12 Jun 2007 Portlets are powerful tools for aggregating data from multiple locations,
integrating different applications, and providing a collaborative workspace for
groups of users. Apache Pluto is the reference implementation of the Portlet
specification, so it's a good choice for testing portlets that are in development.
This article teaches you how to install and configure the Pluto portlet container
inside the Apache Geronimo server.
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.
Install Geronimo
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.
Install Pluto
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.
Map security
roles
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.
Modify Castor properties
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
Deploy the
Pluto TestSuite
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.
Write 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.)
Write the
portlet class
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.jar in
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!
Build and
deploy the portlet
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
Conclusion
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.
Download | Description | Name | Size | Download method |
|---|
| Eclipse 3.2 workspace and deployment plans | pluto-geronimo-example.zip | 3MB | HTTP |
|---|
Resources 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
Discuss
About the author  | 
|  | 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. |
Rate this page
|