SeamFramework.orgCommunity Documentation

Chapter 40. Seam on IBM's WebSphere AS v7

40.1. WebSphere AS environment and version recommendation
40.2. Configuring the WebSphere Web Container
40.3. Seam and the WebSphere JNDI name space
40.3.1. Strategy 1: Specify which JNDI name Seam must use for each Session Bean
40.3.2. Strategy 2: Override the default names generated by WebSphere
40.3.3. Strategy 3: Use EJB references
40.4. Configuring timeouts for Stateful Session Beans
40.5. The jee5/booking example
40.5.1. Building the jee5/booking example
40.5.2. Deploying the jee5/booking example
40.5.3. Deviation from the original base files
40.6. The jpa booking example
40.6.1. Building the jpa example
40.6.2. Deploying the jpa example
40.6.3. Deviation from the generic base files

WebSphere Application Server v7 is IBM's application server offering. This release is fully Java EE 5 certified.

WebSphere AS being a commercial product, we will not discuss the details of its installation. At best, we will instruct you to follow the directions provided by your particular installation type and license.

First, we will go over some basic considerations on how to run Seam applications under WebSphere AS v7. We will go over the details of these steps using the JEE5 booking example. We will also deploy the JPA (non-EJB3) example application.

All of the examples and information in this chapter are based on WebSphere AS v7. A trial version can be downloaded here : WebSphere Application Server V7

WebSphere v7.0.0.5 is the minimal version of WebSphere v7 to use with Seam. WAS v7.0.0.9 is highly recommended. Earlier versions of WebSphere have bugs in the EJB container that will cause various exceptions to occur at runtime.


You may encounter two exceptions with Seam on WebSphere v7.0.0.5 :
EJBContext may only be looked up by or injected into an EJB

This is a bug in WebSphere v7.0.0.5. WebSphere does not conform to the EJB 3.0 specs as it does not allow to perform a lookup on "java:comp/EJBContext" in callback methods.

This problem is associated with APAR PK98746 at IBM and is corrected in v7.0.0.9.

NameNotFoundException: Name "comp/UserTransaction" not found in context "java:"

Another bug in WebSphere v7.0.0.5. This occurs when an HTTP session expires. Seam correctly catches the exception when necessary and performs the correct actions in these cases. The problem is that even if the exception is handled by Seam, WebSphere prints the traceback of the exception in SystemOut. Those messages are harmless and can safely be ignored.

This problem is associated with APAR PK97995 at IBM and is corrected in v7.0.0.9.

The following sections in this chapter assume that WebSphere is correctly installed and is functional, and a WebSphere "profile" has been successfully created.

This chapter explains how to compile, deploy and run some sample applications in WebSphere. These sample applications require a database. WebSphere comes by default with a set of sample applications called "Default Application". This set of sample applications use a Derby database running on the Derby instance installed within WebSphere. In order to keep this simple we'll use this Derby database created for the "Default Applications". However, to run the sample application with the Derby database "as-is", a patched Hibernate dialect must be used (The patch changes the default "auto" key generation strategy) as explained in Chapter 41, Seam on GlassFish application server. If you want to use another database, it's just a matter of creating a connection pool in WebSphere pointing to this database, declare the correct Hibernate dialect and set the correct JNDI name in persistence.xml.

This step is mandatory in order to have Seam applications run with WebSphere v7. Two extra properties must be added to the Web Container. Please refer to the IBM WebSphere Information Center for further explanations on those properties.

To add the extra properties:

In order to use component injection, Seam needs to know how to lookup for session beans bound to the JNDI name space. Seam provides two mechanisms to configure the way it will search for such resources:

Section 30.1.5, “Integrating Seam with your EJB container” gives detailed explanations on how those mechanisms work.

By default, WebSphere will bind session beans in its local JNDI name space under a "short" binding name that adheres to the following pattern ejblocal:<>.

For a detailed description on how WebSphere v7 organizes and binds EJBs in its JNDI name spaces, please refer to the WebSphere Information Center.

As explained before, Seam needs to lookup for session bean as they appear in JNDI. Basically, there are three strategies, in order of complexity:

  • Specify which JNDI name Seam must use for each session bean using the @JndiName annotation in the java source file,
  • Override the default session bean names generated by WebSphere to conform to the jndi-pattern attribute,
  • Use EJB references.
This strategy is the simplest and fastest one regarding development. It uses the WebSphere v7 default binding mechanism. To use this strategy:
  • Add a @JndiName("ejblocal:<>) annotation to each session bean that is a Seam component.
  • In components.xml, add the following line:
    <core:init jndi-name="java:comp/env/#{ejbName}" />
  • Add a file named WEB-INF/classes/ in the web module with the following content:
  • At the end of web.xml, add the following lines:

That's all folks! No need to update any file during the development, nor to define any EJB to EJB or web to EJB reference!

Compared to the other strategies, this strategy has the advantage to not have to manage any EJBs reference and also to not have to maintain extra files. The only drawback is one extra line in the java source code with the @JndiName annotation

There is no simple way to globally override the default naming strategy for session beans in WebSphere. However, WebSphere provides a way to override the name of each bean.

To use this strategy:

  • Add a file named META-INF/ibm-ejb-jar-bnd.xml in the EJB module and add an entry for each session bean like this:
    <?xml version="1.0" encoding="UTF-8"?>

     <session name="AuthenticatorAction" simple-binding-name="AuthenticatorAction" />
     <session name="BookingListAction" simple-binding-name="BookingListAction" />
    WebSphere will then bind the AuthenticatorAction EJB to the ejblocal:AuthenticatorAction JNDI name
  • In components.xml, add the following line:
    <core:init jndi-name="ejblocal:#{ejbName}" />
  • Add a file named WEB-INF/classes/ as described in strategy 1
  • In web.xml, add the following lines (Note the different ejb-ref-name value):

Compared to the first strategy, this strategy requires to maintain an extra file (META-INF/ibm-ejb-jar-ext.xml), where a line must be added each time a new session bean is added to the application), but still does not require to maintain EJB reference between beans.

This strategy is based on the usage of EJB references, from EJB to EJB and from the web module to EJB. To use it:

This is the most tedious strategy as each session bean referenced by another session bean (i.e. "injected") as to be declared in ejb-jar.xml file. Also, each new session bean has to be added to the list of referenced bean in web.xml

A timeout value has to be set for each stateful session bean used in the application because stateful bean must not expire in WebSphere while Seam might still need them. At the time of writing this document, WebSphere does not provide a way to configure a global timeout at neither the cluster, server, application nor ejb-jar level. It has to be done for each stateful bean individually. By default, the default timeout is 10 minutes. This is done by adding a file named META-INF/ibm-ejb-jar-ext.xml in the EJB module, and declare the timeout value for each bean:

<?xml version="1.0" encoding="UTF-8"?>

  <session name="BookingListAction"><time-out value="605"/></session>
  <session name="ChangePasswordAction"><time-out value="605"/></session>

The time-out is expressed in seconds and must be higher than the Seam conversation expiration timeout and a few minutes higher than the user's HTTP session timeout (The session expiration timeout can trigger a few minutes after the number of minutes declared to expire the HTTP session).

Thejee5/bookingexample is based on the Hotel Booking example (which runs on JBoss AS). Out of the box, it is designed to run on Glassfish, but with the following steps, it can be deployed on WebSphere. It is located in the $SEAM_DIST/examples/jee5/booking directory.

The example already has a breakout of configurations and build scripts for WebSphere. First thing, we are going to do is build and deploy this example. Then we'll go over some key changes that we needed.

The tailored configuration files for WebSphere use the second JNDI mapping strategy ("Override the default names generated by WebSphere") as the goal was to not change any java code to add the @JndiName annotation as in the first strategy.

The steps below are for the WAS version stated above.The ports are the default values, if you changed them, you must substitute the values.

This is the Hotel Booking example implemented in Seam POJOs and using Hibernate JPA with JPA transactions. It does not use EJB3.

The example already has a breakout of configurations and build scripts for many of the common containers including WebSphere.

First thing, we are going to do is build and deploy that example. Then we'll go over some key changes that we needed.

Deploying jpa application is very similar to the jee5/booking example at Section 40.5.2, “Deploying the jee5/booking example”. The main difference is, that this time, we will deploy a war file instead of an ear file, and we'll have to manually specify the context root of the application.

Follow the same instructions as for the jee5/booking sample. Select the examples/jpa/dist-websphere7/jboss-seam-jpa.war file on the first page and on the Map context roots for Web modules page (after the Map virtual host for Web module), enter the context root you want to use for your application in the Context Root input field.

When started, you can now access the application at the http://localhost:9080/<context root>.