SeamFramework.orgCommunity Documentation
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.
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:
Servers/Server Types/WebSphere Application Servers
in the left navigation menu
server1
)
Web Container Settings/Web container
custom properties
and add the following properties:
prependSlashToResource = true
com.ibm.ws.webcontainer.invokefilterscompatibility = true
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:
jndi-pattern
switch on the <core:init>
tag in components.xml
.
The switch can use a special placeholder "#{ejbName}
" that resolves to the unqualified name of the EJB
@JndiName
annotation
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:<package.qualified.local.interface.name>
.
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:
@JndiName
annotation in the java source file,
jndi-pattern
attribute,
@JndiName("ejblocal:<package.qualified.local.interface.name>)
annotation to each session bean that is a Seam component.
components.xml
, add the following line:
<core:init jndi-name="java:comp/env/#{ejbName}" />
WEB-INF/classes/seam-jndi.properties
in the web module with the following content:
com.ibm.websphere.naming.hostname.normalizer=com.ibm.ws.naming.util.DefaultHostnameNormalizer java.naming.factory.initial=com.ibm.websphere.naming.WsnInitialContextFactory com.ibm.websphere.naming.name.syntax=jndi com.ibm.websphere.naming.namespace.connection=lazy com.ibm.ws.naming.ldap.ldapinitctxfactory=com.sun.jndi.ldap.LdapCtxFactory com.ibm.websphere.naming.jndicache.cacheobject=populated com.ibm.websphere.naming.namespaceroot=defaultroot com.ibm.ws.naming.wsn.factory.initial=com.ibm.ws.naming.util.WsnInitCtxFactory com.ibm.websphere.naming.jndicache.maxcachelife=0 com.ibm.websphere.naming.jndicache.maxentrylife=0 com.ibm.websphere.naming.jndicache.cachename=providerURL java.naming.provider.url=corbaloc:rir:/NameServiceServerRoot java.naming.factory.url.pkgs=com.ibm.ws.runtime:com.ibm.ws.naming
web.xml
, add the following lines:
<ejb-local-ref>
<ejb-ref-name>EjbSynchronizations</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home></local-home>
<local>org.jboss.seam.transaction.LocalEjbSynchronizations</local>
</ejb-local-ref>
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
To use this strategy:
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"?>WebSphere will then bind the
<ejb-jar-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee
http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
version="1.0">
<session name="AuthenticatorAction" simple-binding-name="AuthenticatorAction" />
<session name="BookingListAction" simple-binding-name="BookingListAction" />
</ejb-jar-bnd>
AuthenticatorAction
EJB to the ejblocal:AuthenticatorAction
JNDI name
components.xml
, add the following line:
<core:init jndi-name="ejblocal:#{ejbName}" />
WEB-INF/classes/seam-jndi.properties
as described in strategy 1
web.xml
, add the following lines (Note the different ejb-ref-name
value):
<ejb-local-ref>
<ejb-ref-name>ejblocal:EjbSynchronizations</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home></local-home>
<local>org.jboss.seam.transaction.LocalEjbSynchronizations</local>
</ejb-local-ref>
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.
components.xml
, add the following line:
<core:init jndi-name="java:comp/env/#{ejbName}" />
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
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"?>
<ejb-jar-ext
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee
http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-ext_1_0.xsd"
version="1.0">
<session name="BookingListAction"><time-out value="605"/></session>
<session name="ChangePasswordAction"><time-out value="605"/></session>
</ejb-jar-ext>
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/booking
example 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.
Building it only requires running the correct ant command:
ant -f build-websphere7.xml
This will create container specific distribution and exploded archive directories with the websphere7
label.
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.
http://localhost:9060/adminEnter your userid and/or your password if security is enabled for the console.
WebSphere enterprise applications
menu option under the Applications --> Application Type
left side menu.
At the top of the Enterprise Applications
table select Install
.
Below are installation wizard pages and what needs to done on each:
Preparing for the application installation
Browse to the examples/jee5/booking/dist-websphere7/jboss-seam-jee5.ear
file using the file upload widget.
Select the Next
button.
Select the Fast Path
button.
Select the Next
button.
Select installation options
Select the "Allow EJB reference targets to resolve automatically
"
check boxes at the bottom of the page. This will let WebSphere use its simplified JNDI reference mapping.
Select the Next
button.
Map modules to servers
No changes needed here as we only have one server. Select the Next
button.
Map virtual hosts for Web modules
No changes needed here as we only have one virtual host. Select the Next
button.
Summary
No changes needed here. Select the Finish
button.
Installation
Now you will see WebSphere installing and deploying your application.
When done, select the Save
link and you will be returned to the
Enterprise Applications
table.
To start the application, select the application in the list, then click on the Start
button at the top of the table.
You can now access the application at http://localhost:9080/seam-jee5-booking
resources-websphere7
directory.
META-INF/ejb-jar.xml
— Removed all the EJB references
META-INF/ibm-ejb-jar-bnd.xml
— This WebSphere specific file has been added as we use the second JNDI mapping strategy.
It defines, for each session bean, the name WebSphere will use to bind it in its JNDI name space
META-INF/ibm-ejb-jar-ext.xml
— This WebSphere specific file defines the timeout value for each stateful bean
META-INF/persistence.xml
— The main changes here are for the datasource JNDI path,
switching to the WebSphere transaction manager lookup class,
turning off the hibernate.transaction.flush_before_completion
toggle,
and forcing the Hibernate dialect to be GlassfishDerbyDialect
as we are using the integrated Derby database
WEB-INF/components.xml
— the change here is jndi-pattern
to use ejblocal:#{ejbname}
as using the second
JNDI matching strategy
WEB-INF/web.xml
— Remove all the ejb-local ref
except the one for
EjbSynchronizations
bean.
Changed the ref fo this bean to ejblocal:EjbSynchronizations
import.sql
— due to the customized hibernate Derby dialect, the ID
column can not be populated by this file and was removed.
Also the build procedure has been changed to include the log4j.jar
file
and exclude the concurrent.jar
and jboss-common-core.jar
files.
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.
Building it only requires running the correct ant command:
ant websphere7
This will create container specific distribution and exploded archive directories with the
websphere7
label.
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>
.
resources-websphere7
directory.
META-INF/persistence.xml
— The main changes here are for the datasource JNDI path,
switching to the WebSphere transaction manager look up class,
turning off the hibernate.transaction.flush_before_completion
toggle,
and forcing the Hibernate dialect to be GlassfishDerbyDialect
how as using the integrated Derby database
import.sql
— due to the customized hibernate Derby dialect, the ID
column can not be populated by this file and was removed.
Also the build procedure have been changed to include the log4j.jar
file
and exclude the concurrent.jar
and jboss-common-core.jar
files.