ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

OpenEJB: EJB for Tomcat
Pages: 1, 2

Configuring Tomcat

Tomcat is a servlet container and as such, doesn't host EJBs. That's where OpenEJB comes onto the scene. It's a EJB container. The role of OpenEJB is to create a runtime environment to run EJBs and let others access them in a unified way. Regardless of which application wants to access the beans, they all do it the same way, by accessing the appropriate Java Naming and Directory Interface (JNDI) context and looking up a home object. Think about JNDI as a catalog of names with objects bound to them. JNDI Initial Context is the starting point when working with the catalog--looking up a name or accessing the object bound to it.



This article has been tested under Jakarta Tomcat 4.1.18. Make sure you aren't using the older version.

OpenEJB can run in two modes: Local (AKA IntraVM) Server and Remote Server. The difference is the approach with which they're initialized and then accessed. OpenEJB Local Server requires some OpenEJB-specific .jars to be available in a client's classpath. It will start automatically the first time the JNDI Initial Context is created. The Remote Server must be booted manually. The above command line session demonstrates how this is done for OpenEJB Remote Server. Technically, OpenEJB Local Server is nothing more than OpenEJB Remote Server that doesn't listen on ports, so remote clients cannot connect.

As previously mentioned, Tomcat knows nothing about EJBs other than that it allows them to be bound in its naming hierarchy, so that JSPs and servlets can access them. These names are merely names when no EJB container hosts the beans tied to them. We are about to see the bridge from Tomcat to the OpenEJB runtime environment. The bridge is an JNDI Object Factory. The factory builds objects on the fly when they are requested from a naming system. The OpenEJB TomcatEjbFactory class intercepts bean requests and passes them to OpenEJB. OpenEJB services the request and responds back appropriately.

If you want to find out more on the TomcatEjbFactory class, read this document.

Installation of the factory requires some OpenEJB classes to be available for Tomcat. This is accomplished by deploying a simple web application to Tomcat that loads OpenEJB .jars into Tomcat's class path. A sample application ships with OpenEJB. When Tomcat starts, the web application is deployed and the application's loader servlet executes, loading the .jars.

Deploying the web application boils down to deploying openejb_loader-0.9.0.war from the <OPENEJB_HOME>/dist directory to the <CATALINA_HOME>/webapps directory. Tomcat searches this directory for web applications to deploy when it starts.

You can configure the way the web application works. Edit its deployment descriptor (/WEB-INF/web.xml) and you'll see the configuration options as <init-param>s of the loader servlet:

  • openejb.home: the path where OpenEJB is installed.
  • openejb.configuration: the OpenEJB configuration file.
  • openejb.localcopy: is OpenEJB supposed to copy all variables between beans?

Don't forget to uncomment and update openejb.home, or OpenEJB won't be able to find its classes. Once the value has changed, restart Tomcat.

The last step is configuring TomcatEjbFactory in Tomcat's default configuration file (server.xml). EJB name bindings appear between <Context> elements of the web application whose components use the bean. The sample EJB binding is shown below.

Place the following declaration between <Context> elements of Tomcat's examples web application.

<Ejb name="ejb/hello"
    type="Session"
    home="org.acme.HelloHome"
    remote="org.acme.Hello"/>
<ResourceParams name="ejb/hello">
    <parameter>
        <name>factory</name>
        <value>org.openejb.client.TomcatEjbFactory</value>
    </parameter>
    <parameter>
        <name>openejb.naming.factory.initial</name>
        <value>org.openejb.client.LocalInitialContextFactory</value>
    </parameter>
    <parameter>
        <name>openejb.naming.security.principal</name>
        <value>username</value>
    </parameter>
    <parameter>
        <name>openejb.naming.security.credentials</name>
        <value>password</value>
    </parameter>
    <parameter>
        <name>openejb.naming.provider.url</name>
        <value>localhost:4201</value>
    </parameter>
    <parameter>
        <name>openejb.ejb-link</name>
        <value>Hello</value>
    </parameter>
</ResourceParams>

The <Ejb> element and its corresponding <ResourceParams> declares that the name ejb/hello points to a session bean whose remote interface is org.acme.Hello, and whose home interface is org.acme.HelloHome.

With the <Ejb> element come <ResourceParams> parameters. These parameters configure Tomcat to know that whenever the ejb/hello name is accessed, the factory (of org.openejb.client.TomcatEjbFactory) should fullfil the request. Other <parameter>s configure the TomcatEjbFactory itself, which has to know how to access the OpenEJB server. One of the <parameter>s is <openejb.ejb-link>, which maps the name from Tomcat to OpenEJB. These are two separate naming systems. Each has its own naming space, and the names in one must be linked to their counterparts in the other.

OpenEJB does not need to be started manually in this configuration. As indicated by the <openejb.naming.factory.initial> parameter's value, it will be done automatically. Changing the value to org.openejb.client.RemoteInitialContextFactory says to connect to OpenEJB that listens to requests at localhost on port 4201. Assuming you have not changed the OpenEJB configuration, it listens on port 4201.

You can find more configuration information in the OpenEJB TomcatEjbFactory documentation.

Let's test the configuration. Start up Tomcat and look at the output. You should see something like the following:

> ./bin/catalina.sh run        
Using CATALINA_BASE:   /disk/home/jacekl/artykul/jakarta-tomcat-4.1.18
Using CATALINA_HOME:   /disk/home/jacekl/artykul/jakarta-tomcat-4.1.18
Using CATALINA_TMPDIR: /disk/home/jacekl/artykul/jakarta-tomcat-4.1.18/temp
Using JAVA_HOME:       /opt/java1.3
[INFO] Registry - -Loading registry information
[INFO] Registry - -Creating new Registry instance
[INFO] Registry - -Creating MBeanServer
[INFO] Http11Protocol - -Initializing Coyote HTTP/1.1 on port 8080
Starting service Tomcat-Standalone
Apache Tomcat/4.1.18
OpenEJB 0.9.1    build: 20030118-2102
http://openejb.sf.net
[INFO] Http11Protocol - -Starting Coyote HTTP/1.1 on port 8080
[INFO] ChannelSocket - -JK2: ajp13 listening on 0.0.0.0/0.0.0.0:8009
[INFO] JkMain - -Jk running ID=0 time=4/317 
	config=/disk/home/jacekl/artykul/jakarta-tomcat-4.1.18/conf/jk2.properties

As you might have noticed, OpenEJB has also started while Tomcat was initializing the example web application's resources. This is because the factory had been told to boot OpenEJB Local Server via the openejb.naming.factory.initial parameter. Therefore, in this configuration, Tomcat will start up OpenEJB as well.

Creating and Deploying the Web Application

Having configured Tomcat and the factory, we are now able to look up ejb/hello in Tomcat's naming space and expect to get hold of the Hello EJB deployed in OpenEJB.

This code shows how simple it is. Download it here.

Example 1 -- openejb.jsp

<%@ page import="org.acme.HelloObject,
	org.acme.HelloHome,
	javax.naming.InitialContext,
	javax.naming.Context"%>

<html>
<head>
	<title>OpenEJB -- EJB for Tomcat</title>
</head>

<body>
Stateless Session bean - HelloBean - says:
<%
	Context initCtx = new InitialContext();

	Object object = initCtx.lookup("java:comp/env/ejb/hello");
	HelloHome helloHome = (HelloHome)
		javax.rmi.PortableRemoteObject.narrow(object, HelloHome.class);
	HelloObject bean = helloHome.create();
%>
<%= bean.sayHello() %>
</body>
</html>

Assuming you haven't tweaked Tomcat's configuration too much, save the file in $CATALINA_HOME/webapps/examples. Tomcat's example web applications reside there, and saving the file there shortens the path of deploying a separate web application. (Also, we don't have to learn too much about Tomcat configuration in this article.)

Running the Example

Now it's time to see it working. Start up Tomcat and browse to this URL: http://localhost:8080/examples/openejb.jsp .


Figure 1 -- our application in action

Summary

When EJB is mentioned, a few products come to mind. They usually require some time working with configuration files before they're started up and functioning well, especially when combined with Tomcat. Sometimes it's not possible at all. More importantly, they always require installing another platform on your computer that replaces the standalone Tomcat with some platform where Tomcat is a service of some kind. You won't be happy if you've already invested time learning the standalone Tomcat.

As you might have seen, OpenEJB is quite different. Installation boils down to deploying an OpenEJB web application and setting up Tomcat so that some of the JNDI names point to the OpenEJB naming system. Nothing more than that; no changes to already-deployed web applications, no additional configuration files in Tomcat, and frankly, you won't be tied to a specific Tomcat version. So, do we need more benefits? They're coming ...

If anybody says EJB containers require a lot of time to grasp, mention OpenEJB. The development of OpenEJB is ongoing, so it's possible to see more features pertaining to the integration in the future. Make sure to visit the OpenEJB home page often.

Jacek Laskowski is a technical consultant at Hewlett-Packard. In his spare time, he contributes to OpenEJB development.


Return to ONJava.com.