Apache Tomcat Overview

Apache Tomcat is an implementation of the Java Servlet and JavaServer Pages technologies. The Java Servlet and JavaServer Pages specifications are developed under the Java Community Process. Although Tomcat is not a full Java Enterprise Application Server, such as Geronimo or JBoss, Tomcat still has many advanced features of an applications server. Tomcat is not an portal server nor is it portlet container. Jetspeed is both a portal server and includes a portlet container. To find out more about portlet containers, see the Pluto project. The Jetspeed installer comes with a pre-packaged release of Tomcat built-in.

Tomcat Versions Supported

Jetspeed 2.3.0 is well tested and integrated to run on the following Apache Tomcat platforms:

  • Latest Tomcat 7.0.59+ - recommended for Servlet API 3.0.1 / JSP 2.2.1

How Jetspeed runs in Tomcat

Jetspeed is a normal web application, thus it runs in Tomcat like any other web application. However, since Jetspeed is also a portal server, with the ability to include content from other deployed portlet applications in the application server, it has a few special requirements in order for it to run in Tomcat:

  • Cross Context Invocation - Jetspeed must be configured in Tomcat to execute cross-context request dispatching.
  • Database Configuration - By default, Jetspeed lets Tomcat manage the database connections. Tomcat requires a context file be provided in order for Jetspeed to use Tomcat connection pooling
  • Common Class Loader - Jetspeed requires loading several jars in Tomcats shared class loader. The classes from these jars are shared between Jetspeed and all portlet applications
  • Renaming the Context Path - you can give Jetspeed a different context path name
  • Configuring a JAAS Realm - you can configure JAAS Realm features in Tomcat specific to Jetspeed like providing your own role and user classes

Getting Jetspeed to run in Tomcat requires some minimal configuration describing in the following section. If you run the Jetspeed installer, which comes with Tomcat built-in, all the configuration is managed by the installer program for you.

Tomcat Configuration

Tomcat uses XML files to configure Tomcat-specific features as well as standardized features. The WEB-INF/web.xml file configures the standard features. Some Tomcat specific features for web applications, not explicity covered by the servlet specification, are configured in the META-INF/context.xml file. Several of Tomcat specific configurations required to configure Jetspeed without the installer are: database, cross-context requests, and the common-class-loader. Also note, If you build Jetspeed using the Maven build tools, Jetspeed will create this Tomcat context file for the Jetspeed web application and deploys it to Tomcat automatically.

Here is an example of a context.xml file for Jetspeed:


<Context crossContext="true">

  <Realm className="org.apache.catalina.realm.JAASRealm"
         appName="Jetspeed"
         userClassNames="org.apache.jetspeed.security.impl.UserPrincipalImpl"
         roleClassNames="org.apache.jetspeed.security.impl.RolePrincipalImpl"
         useContextClassLoader="true"
         debug="0"/>


	<Resource name="jdbc/jetspeed" auth="Container"
            factory="org.apache.commons.dbcp.BasicDataSourceFactory"
            type="javax.sql.DataSource" username="j2" password="secret"
            driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/jetdb"
            maxActive="100" maxIdle="30" maxWait="10000"/> 

	<Valve className="org.apache.catalina.authenticator.FormAuthenticator" characterEncoding="UTF-8"/>

</Context>

Tomcat Cross-Context Configuration

First thing you will notice about the Tomcat context file is the cross context setting set to true, which is *not* the default:


<Context crossContext="true">

This setting is required for Jetspeed to "aggregate" content from different portlet applications all onto the same page. But default, Tomcat does not enable this feature. Please make sure this setting is true, or Jetspeed will not function properly.

Tomcat Database Configuration

This context file also holds the JDBC configuration for the database used by Jetspeed internally. By default, Jetpeed looks up database connections with JNDI. Thus Jetspeed expects you that you configure your database connections in your particular application server configuration. In the case of Tomcat, here is the database configuration necessary to setup a required JNDI resource name jdbc/jetspeed:


<Context crossContext="true">

...
	<Resource name="jdbc/jetspeed" auth="Container"
            factory="org.apache.commons.dbcp.BasicDataSourceFactory"
            type="javax.sql.DataSource" username="j2" password="secret"
            driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/jetdb"
            maxActive="100" maxIdle="30" maxWait="10000"/> 

...

</Context>

We have configured several important features of the database configuration specific to Tomcat including:

attribute description
factory The JDBC Data Source Factory class name. Here we make use of the Apache Commons DBCP (Database Connection Pooling) library
type javax.sql.DataSource - the type of resource: a JDBC DataSource provider
username The username in the database that will be used to authenticate
password The password of the user on the database
driverClassName The classname of the JDBC database driver: specific to the database being used by Jetspeed
url The JDBC Database connection URL string
maxActive Maximum number of active database connections
maxIdle Maximum number of idle database connections
maxWait Maximum wait time to get a connection in milliseconds before timing out

Also see the Tomcat documentation for more details on configuring database connection pools and JNDI in Tomcat

Common Class Loader in Tomcat shared/lib

Jetspeed requires loading several jars in Tomcats shared class loader. The classes from these jars are shared between Jetspeed and all portlet applications.

Jetspeed and portlet applications are deployed as separate web applications. Jetspeed runs as a MVC-Controller-type servlet, running in a standalone web(portlet) application. Each portlet application runs in its own web application. The Portal then dispatches to portlets using cross-context invocation

This means that parts of Jetspeed must exist in common class loaders shared amongst all web applications in the application server. As the diagram below depicts, the shared/lib class loader takes precedence over the individual portlet application class loaders:

To summarize, you must place the following jars in Tomcat's shared library directory (lib):

ls $TOMCAT_HOME/lib
...
apa-logging-1.1.jar
ccpp-1.0.jar
jetspeed-api-2.3.0.jar
jetspeed-commons-2.3.0.jar
pluto-container-api-2.0.3.jar
pluto-taglib-2.0.3.jar
portals-bridges-common-2.1.jar
portlet-api_2.1.0_spec-1.0.jar

Additionally, you may want to put your JDBC driver here, for example:

mysql-connector-java-5.1.6-bin.jar

Deploying Portlet Applications to Tomcat

Portlets are similar to servlets. They require a deployment descriptor, called the portlet.xml placed in the WEB-INF directory in addition to the web.xml required by servlet applications. Portlet Applications need to be packaged in the same WAR format specified for servlets. In order to deploy a portlet, Jetspeed-2 requires the user to follow those steps:

  • Build your portlets as a portlet application just as you would a web application.
  • Package your portlet application into a .war file, along with a WEB-INF/portlet.xml descriptor.
  • Copy the .war file to Jetspeed's deployment directory, by default this is WEB-INF/deploy. Jetspeed will take care of automatically deploying the portlet application into the application server (Tomcat), and then registering the portlets into the portlet registry.

Alternatively, you can copy directly into Tomcat's webapps directory, but only if you have infused your portlet application with the necessary settings in your web.xml.

You can also copy over a portlet-application's web.xml or portlet.xml to cause re-registration of the portlet application.

Infusing Jetspeed Servlet in your Application

Jetspeed requires that a Jetspeed Container servlet be placed in your portlet application's web.xml. This servlet's class file is actually stored in the Jetspeed shared library path, so you do not have to include it into your portlet application distribution. Again, when dropping into Jetspeed's deploy directory, this procedure is not necessary, as the servlet will be automatically added to your web.xml by the Jetspeed deployer. This servlet allows Jetspeed to communicate with your portlet application to invoke cross-context portlet phases (action, render). Additionally, the servlet will attempt to register this portlet application during the servlet initialization phase. A check-sum value on the portlet.xml, web.xml, and jetspeed-portlet.xml is compared for changes, determining if re-registration is necessary.


   <servlet>
    <description>MVC Servlet for Jetspeed Portlet Applications</description>
    <display-name>Jetspeed Container</display-name>
    <servlet-name>JetspeedContainer</servlet-name>
    <servlet-class>org.apache.jetspeed.container.JetspeedContainerServlet</servlet-class>
    <init-param>
      <param-name>contextName</param-name>
      <param-value>j2-admin</param-value>
    </init-param>
    <load-on-startup>100</load-on-startup>
   </servlet>
  
  <servlet-mapping>
    <servlet-name>JetspeedContainer</servlet-name>
    <url-pattern>/container/*</url-pattern>
  </servlet-mapping>

The contextName init parameter defines the context path used by Tomcat and Jetspeed in locating your application. This should be the same as your servlet context path setting for Tomcat.

Finally, you have the option to run the Jetspeed deploy tool to automatically add the above XML to your application's web.xml. Jetspeed provides a Deploy Tool to run during the build process of your portlet application:


    java -jar jetspeed-deploy-tools-<version>.jar -s inputWarPath outputWarPath 

 where: 

 -s: flag indicating whether or not to strip to loggers from the application. When the flag is 
     present, the loggers available in the application will be removed.
      
 inputWarPath: the path of the war to process. 
 outputWarPath: the path of the processed war. 

Tomcat Manager and Jetspeed

Jetspeed knows how to communicate with the Tomcat Manager application. The Tomcat Manager is a simple programmatic API for managing servlet application lifecycle including:

  • Deploy an application
  • Undeploy an application
  • Start an application
  • Stop an application

The Jetspeed PortletApplicationManager portlet requires some Tomcat configuration modifications before it can work correctly. You will need to define an manager-script user in Tomcat's conf/tomcat-users.xml. Make sure to configure your user with the manager-script role.

A minimal example tomcat-users.xml can look like:

						
<tomcat-users>
  <role rolename="manager-script"/>
    <user username="j2deployer" password="xxxxx" roles="manager-script"/>
</tomcat-users>
					
The attribute values for username and password must also be configured in the Jetspeed Override Properties

Advanced Configuration...

Changing the Application Context Path and Docbase

If you would like, you can change the context path and document base of any web or portlet application, including Jetspeed. The context path is the path that identifies the application, such as /jetspeed in a URL like http://localhost:8080/jetspeed/portal. With this feature you can change the name of your portal to say something like /myportal:


<Context path='/myportal' docBase='/opt/myportal'>

Additionally, your application doesn't have to reside in the Tomcat webapps directory. In the example above we have moved it to the /opt/myportal directory.

JAAS Realms, Users and Roles

Jetspeed makes use of its own login module. In that login module, Jetspeed provides its own implementations of User Principals and Role Principals to Tomcat. In order for Tomcat to know about these JAAS (Java Authentication and Authorization Services) classes, we need to tell Tomcat:


  <Realm className="org.apache.catalina.realm.JAASRealm"
         appName="Jetspeed"
         userClassNames="org.apache.jetspeed.security.impl.UserPrincipalImpl"
         roleClassNames="org.apache.jetspeed.security.impl.RolePrincipalImpl"
         useContextClassLoader="true"
         debug="0"/>

Tomcat on Windows

To have redeployment and undeployment working properly when using Tomcat 7.x+ on Windows you have to set the global Context attribute "antiJARLocking" to true in the context.xml file under META-INF.

						
    <Context antiJARLocking="true">
    ...
    </Context>