Apache Pluto and Apache Geronimo: A quick introduction
Apache Pluto is the reference implementation of the Java™ Portlet Specification (JSR 168). Pluto provides the basic, lightweight implementation of container interfaces specified in JSR 168 and a portal driver with other utilities for developing standard portlets. Pluto serves as a basic portlet container that implements the portlet APIs and offers developers a working example platform from which they can host their portlets. Pluto's simple portal component is built only on the portlet container's and JSR 168's requirements.
Apache Geronimo 1.1 is an open source Java 2 Platform, Enterprise Edition (J2EE) 1.4-certified application server. Unlike other J2EE application servers, Geronimo comes preintegrated with external resource components, such as a database, a messaging server, and a directory server. Geronimo is built on a highly customizable and modular architecture. It functions as a framework supporting existing components to form a complete J2EE application server package composed of more than 30 best-of-breed open source projects. Geronimo comes preintegrated with either Apache Tomcat or Apache Jetty; this article uses the Tomcat version of Geronimo.
Although Apache Pluto comes as a Web application built on J2EE standards, it can't be directly deployed as is. Also, any Pluto portal application you develop can't be directly installed in the Pluto portal container. Developers typically deploy Pluto in the Apache Tomcat Web container, but that approach isn't your only choice. Geronimo can also host Pluto applications. This article shows how to use the Pluto portal server with Geronimo to provide a completely open source testing and deployment environment for portal applications with a popular and feature-rich application server in the background.
The procedure for deploying and executing Web applications in Geronimo differs from the procedure in Tomcat. The rest of this article shows you how to deploy and execute a sample portal application in Pluto hosted on Geronimo by completing the following steps:
- Share Pluto libraries and properties through the
sharedlibmodule. - Create a Geronimo deployment plan for the Pluto container and driver.
- Deploy Pluto in Geronimo.
- Develop a sample portal application.
- Create a required deployment plan for the sample portal application.
- Deploy and test the sample portal application on Geronimo.
To get started, download and install and extract both Geronimo and Pluto (see the Resources section for the download links). I'll refer to the directory where you install Geronimo as GERONIMO_HOME. You can download Pluto as either a source or binary distribution. According to the Pluto Installation Guide, "installing the source distribution requires the most effort, and is recommended only for those individuals who are interested in modifying the container." I'll refer to the downloaded binary distribution's location as PLUTO_HOME and to the source location as PLUTO_SRC. (When I point you to file locations in PLUTO_HOME, you can locate the same files if you've built the source distribution.)
Share Pluto libraries and properties
In Tomcat, Pluto deploys portal applications as a subpart of the Pluto container Web application. This approach isn't feasible in Geronimo. Deploying a new application means creating new Web-application and Geronimo deployment plans. However, there's no way to update the plans and deployment configuration dynamically after the application is deployed. One way to get around this problem is to deploy all the portal applications as external applications and, in Pluto, configure the new portal application to be redirected to the external application. The configuration includes defining portlets and portals in the Pluto registry. This solves the initial problem but opens up a bundle of new ones.
One major problem is that because the applications are deployed separately, they all use different class loaders. This means that the Portlet API classes, Pluto container classes, and common services classes are loaded in separate class loaders for the Pluto application and your portal application, resulting in many ClassNotFoundExceptions.
To solve this problem, all the common Pluto files need to be loaded in the same class loader. A service in Geronimo 1.1 called sharedlib lets you do this. Using this service, you can store the common class files and libraries in a shared folder. An application that wants to use the shared files can do so by configuring itself to be dependent on the sharedlib service.
To use sharedlib in Pluto, copy the following files to the GERONIMO_HOME\var\shared\classes folder from PLUTO_HOME\webapps\pluto\WEB-INF\classes:
- pluto-admin.properties
- castor.properties
- logging.properties
And copy the following files to GERONIMO_HOME\var\shared\lib folder from the PLUTO_HOME\shared\lib and PLUTO_HOME\webapps\pluto\WEB-INF\lib folders:
- pluto-1.0.1.jar
- pluto-deploy-1.0.1.jar
- pluto-descriptors-1.0.1.jar
- pluto-portal-1.0.1.jar
- portlet-api-1.0.jar
- castor-0.9.5.3.jar
- commons-fileupload-1.1.jar
- commons-io-1.1.jar
Make sure that the geronimo/sharedlib/1.1.1/car service is started when Geronimo server starts.
Create a Geronimo deployment plan for Pluto
All applications in Geronimo require a Geronimo deployment plan if they use external resource references, such as security configurations or dependency aspects. As you just learned, the Pluto container and driver applications must be deployed in Geronimo with a dependency on the sharedlib service. The Pluto container and driver applications and the Pluto server application are Web applications, so their deployment plan will be a Geronimo Web deployment plan.
A Geronimo deployment plan is more or less like a J2EE deployment descriptor; the difference is that a Geronimo deployment plan contains server-specific information. Listing 1 shows the commonly used Pluto server application's Geronimo Web deployment plan.
Listing 1. Pluto deployment plan for Geronimo -- geronimo-web-pluto.xml
<?xml version="1.0"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/web"
xmlns:naming="http://geronimo.apache.org/xml/ns/naming"
xmlns:tomcat="http://geronimo.apache.org/xml/ns/web/tomcat/config-1.0"
xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1">
<sys:environment>
<dependencies>
<dependency>
<artifactId>sharedlib</artifactId>
</dependency>
</dependencies>
</sys:environment>
<security-realm-name>pluto-properties-file-realm</security-realm-name>
<security>
<default-principal realm-name="pluto-properties-file-realm">
<principal class=
"org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" name="user"/>
</default-principal>
<role-mappings>
<role role-name="tomcat">
<realm realm-name="pluto-properties-file-realm">
<principal class=
"org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"
name="admin"/>
<principal class=
"org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"
name="system"/>
</realm>
</role>
</role-mappings>
</security>
<tomcat:cross-context/>
</web-app>
|
You can see that the deployment plan in Listing 1 has three major configurations:
- Dependency: The
<dependency>element is used to specify a Web application's dependency on any other module, application, or service. It can also indicate dependency on third-party libraries located in the Geronimo repository. In Listing 1,<artifactId>sharedlib</artifactId>within the<dependency>element specifies the dependency on thesharedlibservice. - Security: The Pluto Web application requires security to be configured. Specifically, it requires that
<security-realm>be used to authenticate user logins and principals, and<role-mappings>to map roles defined in Pluto's Web deployment descriptor (web.xml). In Listing 1, thepluto-properties-file-realmsecurity realm is configured to enforce application-specific authentication policy, which acts as an entry point into login domains. It's configured to useorg.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal. Thetomcatrole defined in the Pluto application's web.xml file is mapped to use thissecurity-realm. - Cross context: One of the essential features Pluto server requires is the ability to invoke portlets present in another Web application deployed on Geronimo server. By default, this feature -- which lets one Web application dispatch requests to a different Web application -- is not enabled. You can enable it by specifying a
<cross-context>element in the deployment plan. The presence of<tomcat:cross-context/>in Listing 1 activates this feature for the Pluto server application.
If you downloaded the Pluto source distribution, you can build it to get the Pluto Web application PLUTO_SRC\pluto\portal\target\pluto.war. If you're using the binary Pluto distribution, create pluto.war from the PLUTO_HOME\webapps\pluto folder using the following command (where pluto_xxx is a folder of your choice):
c:\pluto_xxx>jar cvf pluto.war
After you have pluto.war, deploy it using the Web console or command-line deployment tool (type the following command on a single line):
c:\geronimo-1.1.1\bin>deploy --user system deploy
c:\pluto_xxx\pluto.war c:\pluto_xxx\geronimo-web-pluto.xml
Develop the sample portal application
As a sample scenario to demonstrate the development and deployment of a portal application, you'll develop an application for purchasing tickets. Because you're developing a JSR 168- and J2EE-based application, the server setup for portal applications for Pluto deployed in Geronimo is no different from any other server setup. To create sample portal application, you need to create four files:
- Portlet class
- Portlet descriptor
- Web application descriptor
- Portlet view page
A detailed explanation of the content of these files is beyond this article's scope. Read "Build and test JSR 168-compliant portlets with Apache Pluto" (developerWorks, April 2006) for more information.
Each portlet in a portal class has a portlet class that implements the javax.portlet.Portlet interface. To facilitate this, JSR 168 defines a default implementation for javax.portlet.Portlet -- the javax.portlet.GenericPortlet class. Listing 2 shows the org.sample.geronimo.buyticket.BuyTicketPortlet class, which extends GenericPortlet for the BuyTicket portlet. Similarly, this article's sample code includes an org.sample.geronimo.buyticket.TShirtPortlet (see the Download section).
Listing 2. The portlet class -- org.sample.geronimo.buyticket.BuyTicketPortlet
package org.sample.geronimo.buyticket;
import java.io.*;
import javax.portlet.*;
import org.apache.pluto.portlet.admin.util.PlutoAdminContext;
public class BuyTicketPortlet extends GenericPortlet {
private static String VIEW_JSP = "/view.jsp";
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
response.setContentType(request.getResponseContentType());
PortletContext context = getPortletConfig().getPortletContext();
context.getRequestDispatcher(VIEW_JSP).include(request, response);
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, java.io.IOException {
String game = request.getParameter("game");
String name = request.getParameter("name");
String card = request.getParameter("card");
String errorMessage = null;
if(game != null && name != null && card != null
&& !game.equals("") && !name.equals("")
&& !card.equals("")){
response.setRenderParameter("game", game);
response.setRenderParameter("name", name);
}else
response.setRenderParameter("errorMessage",
"You entered invalid data, please check the name and credit information");
}
}
|
The portlet.xml file shown in Listing 3 provides information, such as portlet name, title, class, and mode, for all the portlets contained in the portal application.
Listing 3. The portlet descriptor -- portlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
id="org.sample.geronimo.buyticket.BuyTicketPortlet">
<portlet>
<portlet-name>BuyTicket</portlet-name>
<display-name>Buy Ticket Portlet</display-name>
<portlet-class>
org.sample.geronimo.buyticket.BuyTicketPortlet
</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>Buy Ticket Title</title>
</portlet-info>
</portlet>
<portlet>
<portlet-name>TShirt</portlet-name>
<display-name>TShirt Portlet</display-name>
<portlet-class>
org.sample.geronimo.buyticket.TShirtPortlet
</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>TShirt</title>
</portlet-info>
</portlet>
</portlet-app>
|
web.xml is a standard J2EE-specified XML descriptor used to provide information about a Web application component, such as servlets and taglibs. Listing 4 shows the WEB-INF\web.xml file for the buyticket portal application.
Listing 4. The Web application descriptor -- WEB-INF\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">
<web-app>
<display-name>GetPortlet</display-name>
<servlet>
<servlet-name>BuyTicket</servlet-name>
<display-name>BuyTicket Wrapper</display-name>
<description>Automated generated Portlet Wrapper</description>
<servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-guid</param-name>
<param-value>buyticket.BuyTicket</param-value>
</init-param>
<init-param>
<param-name>portlet-class</param-name>
<param-value>org.sample.geronimo.buyticket.BuyTicketPortlet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>BuyTicket</servlet-name>
<url-pattern>/BuyTicket/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>TShirt</servlet-name>
<display-name>TShirt Wrapper</display-name>
<description>Automated generated Portlet Wrapper</description>
<servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-guid</param-name>
<param-value>buyticket.TShirt</param-value>
</init-param>
<init-param>
<param-name>portlet-class</param-name>
<param-value>org.sample.geronimo.buyticket.TShirtPortlet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>TShirt</servlet-name>
<url-pattern>/TShirt/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>http://java.sun.com/portlet</taglib-uri>
<taglib-location>tld/portlet.tld</taglib-location>
</taglib>
<taglib id="PortletTLD">
<taglib-uri>http://java.sun.com/portlet</taglib-uri>
<taglib-location>/WEB-INF/tld/portlet.tld</taglib-location>
</taglib>
</web-app>
|
BuyTicketPortlet includes a view page to decouple the view part from portlet code by calling context.getRequestDispatcher("view.jsp").include(request, response);. The view.jsp file, shown in Listing 5, is used to render the actual HTML page.
Listing 5. The initial page -- view.jsp
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<portlet:defineObjects />
<%
String game = renderRequest.getParameter("game");
if (game == null) game = "";
String name = renderRequest.getParameter("name");
if (name == null) name = "";
String errorMessage = renderRequest.getParameter("errorMessage");
if (errorMessage != null) {
%>
<p><%=errorMessage%></p>
<%
}else if (name != null && !name.equals("") && game != null && !game.equals("") ) {
%>
<p><b> Thank you <%= name %>, you purchased ticket for <%= game %></b></p>
<%
}
%>
<FORM name="<portlet:namespace/>ticketform" action="<portlet:actionURL/>">
<table border="0">
<tr><td>
Select Game/Event
</td><td>
<select name="game">
<%
java.util.ArrayList map=org.sample.geronimo.buyticket.GameConstants.map;
java.util.Iterator itr=map.listIterator();
while(itr.hasNext())
{
String gamelist=(String)itr.next();
%>
<option value=<%= gamelist %> selected="true"><%= gamelist %></option>
<%
}
%>
</select>
</td></tr>
<tr><td>Name</td><td><INPUT type="text" name="name" size="20"/></td></tr>
<tr><td>Card</td><td><INPUT type="text" name="card" size="20"/></td></tr>
<tr><td>Exp. Date</td><td><INPUT type="text" name="date" size="20"></td></tr>
</table>
<INPUT type="submit" name="<portlet:namespace/>submitTicket" value="Buy"/>
<INPUT type="submit" value="Cancel"/>
</FORM>
|
Now copy the portlet.tld file from PLUTO_HOME\webapps\pluto\WEB-INF\tld into the WEB-INF\tld folder. Compile the Java files in the WEB-INF\classes folder, and package all the above files as a WAR file, like this:
c:\buyticket>jar -cvf buyticket.war
Create a deployment plan for the sample application
When Pluto is deployed on Geronimo, all portal applications to be deployed in Pluto must be deployed as Web applications in Geronimo server. You need a Geronimo Web deployment plan for the buyticket portal application, just as you needed a Pluto server application Web deployment plan. The deployment plan for buyticket -- geronimo-web-app.xml -- is shown in Listing 6.
Listing 6. The portal application deployment plan -- geronimo-web-app.xml
<?xml version="1.0"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/web"
xmlns:naming="http://geronimo.apache.org/xml/ns/naming"
xmlns:tomcat="http://geronimo.apache.org/xml/ns/web/tomcat/config-1.0"
xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1">
<sys:environment>
<dependencies>
<dependency>
<artifactId>sharedlib</artifactId>
</dependency>
</dependencies>
</sys:environment>
</web-app>
|
The Pluto portal application requires common Pluto files, which are shared via the sharedlib service in Geronimo. The portal application's dependency on the sharedlib service is specified in the portal application deployment plan in Listing 6.
Deploy and test the sample application on Geronimo
The portal application must go through two levels of deployment. At the first level it's deployed in Geronimo as a Web application. You can do this easily by using the Geronimo deploy tool:
- Type the following command on a single line:
c:\geronimo-1.1.1\bin>deploy --user system deploy c:\buyticket\buyticket.war
c:\buyticket\geronimo-web-app.xml
This command deploys the application as a Web application in Geronimo, but to use the Pluto services and features, the application must be redirected through Pluto (the second deployment level). - To do this, you must store the application configuration information in the Pluto registry. You can update the pluto\WEB-INF\data\pageregistry.xml, pluto\WEB-INF\data\portletcontexts.txt, and pluto\WEB-INF\data\portletentityregistry.xml files manually. Or you can use the Pluto admin application by going to the next step.
- Open http://localhost:8080/pluto/portal, and click the Admin link. This opens the http://localhost:8080/pluto/portal/adminportletapp application shown in Figure 1.
Figure 1. Pluto admin application -- deploy buyticket portlet application
- In this application, browse to the buyticket.war file, and click Submit. This deploys the
buyticketapplication and adds a portal application specific configuration to portletentityregistry.xml. - In the next page of admin deployment, provide the title, description, and layout information for the newly deployed portal application (see Figure 2).
Figure 2. Pluto admin application -- portal layout
- Change the number of rows and columns to show how many your portal application contains.
- Next, select the portlet to be displayed in each row and column, as shown in Figure 3.
Figure 3. Pluto admin application -- define page layout
In this step, pageregistry.xml is updated with layout settings for portlet positioning in the portal application. This step completes the job of deploying a portal application in Pluto server working on Geronimo. - Now you can start testing and using your application by clicking the buyticket link. Figure 4 shows the
buyticketapplication deployed and running in Pluto server.
Figure 4. The buyticket portal application
Apache Pluto is a small and easily usable portal test bed for JSR 168-compliance testing. Portal server support isn't preintegrated in Geronimo, but any portal server -- such as Pluto, Jetspeed, or Liferay -- can be installed in Geronimo as a plug-in or external application. Even if you bring in a heavy player like Jetspeed or Liferay as the deployment environment, only Pluto can fulfill the requirement for lightweight development and testing. By integrating Pluto with Geronimo, you gain a portal environment that combines the best of the open source portal server and application server worlds.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample application | buyticket.zip | 14KB | HTTP |
Information about download methods
Learn
- Visit the homes of the Apache Pluto and Apache Geronimo projects.
- Check out the developerWorks Apache Geronimo project area for articles, tutorials, and other resources to help you get started developing with Geronimo today.
- Read "Build and test JSR 168-compliant portlets with Apache Pluto" (developerWorks, April 2006) for a guided tour of portlet testing.
- Learn about JSR 168 and JSR 286 (the next version of the Java Portlet Specification).
- 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® products.
- 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.
- Stay current with developerWorks technical events and webcasts.
- Browse all the Apache articles and free Apache tutorials available in the developerWorks Open source zone.
Get products and technologies
- Download free binary and source versions of Apache Geronimo 1.1 and Apache Pluto.
- Kick start your Java application development with the Eclipse plug-in for Geronimo 1.1.
- 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
- Participate in the discussion forum.
- Join the user mailing list, developer mailing list, and source control mailing list available for Pluto discussions.
- Participate in Pluto JIRA discussions and threads.
- Join the user mailing list, developer mailing list, and source control mailing list available for Geronimo 1.1 discussions.
- Participate in Geronimo 1.1 JIRA discussions and threads.
- Check out developerWorks blogs, and get involved in the developerWorks community.
- Stay up to date on Geronimo developments at the Apache Geronimo blog.

Rakesh Midha is a software architect with IBM Software Labs, Bangalore, currently working on IBM internal open source initiatives. He has eight years of technical experience in Java and C++ server-side programming on multiple platforms and various relational database systems, including IBM DB2® Universal Database™, Oracle, MySQL, and Microsoft SQL Server. He is involved in a number of J2EE applications, product architecture development, and implementation. He is an author of two DB2-related IBM Redbooks and a frequent author on IBM developerWorks. He presented a session entitled "Inside Apache Geronimo 1.1 -- What makes it special?" at ApacheCon Asia in Colombo, Sri Lanka in August 2006. He holds a bachelor's degree in electronics engineering from the Punjab University, Chandigarh, India.



