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.
Jetspeed 2.3.0 is well tested and integrated to run on the following Apache Tomcat platforms:
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:
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 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>
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.
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
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
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:
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.
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.
Jetspeed knows how to communicate with the Tomcat Manager application. The Tomcat Manager is a simple programmatic API for managing servlet application lifecycle including:
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>
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.
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"/>