I'm a JBoss core developer at Red Hat, and the AeroGear project lead. I previously lead the RichFaces project, and have been involved in many other open source projects such as Seam, and JBoss AS. I'm passionate about promoting open source, community, and standards. I server as a W3C representative for Red Hat, and have been part of multiple Java Community Process (JCP) specifications, currently on the JSON API expert group. I have been architecting and developing enterprise applications and projects for over fourteen years, specializing in mobile device integration, web tier frameworks, UI design, and integration.
| Recent Entries |
|
26. Apr 2012
|
|
|
14. Mar 2012
|
|
|
31. Jan 2012
|
|
|
14. Dec 2011
|
|
|
09. Dec 2011
|
|
|
11. Aug 2011
|
|
|
14. Jun 2011
|
|
|
29. Mar 2011
|
|
|
17. Mar 2011
|
|
|
07. Mar 2011
|
|
|
02. Mar 2011
|
|
|
15. Feb 2011
|
|
|
11. Jan 2011
|
|
|
17. Nov 2010
|
|
|
25. Oct 2010
|
The latest release of Seam 2.0.2.SP1 includes a completely updated reference guide chapter for deploying Seam on BEA's Weblogic . The primary focus was on working around several issues with Weblogic and EJB3 support.
We will explain and demonstrate how to get the Seam jee5/booking example installed and running on Weblogic 10.0.MP1. This example demonstrates the use of Seam in a Java EE 5 environment using EJB3 with transaction and persistence context management handled by Weblogic.
What you need
First step we need to install Weblogic 10.0.MP1, and create a domain in Development Mode. You can use either the Sun JDK or the JRockit JDK it does not matter to this example.
For this example we'll refer to the seam distribution directory as $SEAM_DIST, BEA home as $BEA_HOME, and the domain home as $DOMAIN_HOME.
The Weblogic varargs issue
For several release of Weblogic you could not deploy an EJB that used variable arguments in its methods. Weblogic's internal EJB compiler confuses variable arguments as if it was a transient modifier. Seam uses variable arguments in one of its internal EJB's TimerServiceDispatcher, so when deployed this produces an error like this:
java.io.IOException: Compiler failed executable.exec: /jboss/apps/bea/wlserver_10.0/user_projects/domains/seam_examples/servers/AdminServer/cache/EJBCompilerCache/5yo5dk9ti3yo/org/jboss/seam/async/ TimerServiceDispatcher_qzt5w2_LocalTimerServiceDispatcherImpl.java:194: modifier transient not allowed here public transient javax.ejb.Timer scheduleAsynchronousEvent(java.lang.String arg0,java.lang.Object[] arg1)
To work around this issue there are 2 options:
Option 1) Apply the CR327275 patch, but...
BEA has released a patch that addresses the variable arguments issue. It is named CR327275 and can be requested from BEA through their support organization.
Unfortunately an additional issue that this patch either causes, or exposes has been reported and verified by BEA (CR363182). This issue has to do with certain EJB methods incorrectly left out of Weblogic's generated internal stub classes. Some users have reported that this does not effect them - see this 2.0.2.GA release comment for details.
Option 2) Don't deploy TimerServiceDispatcher EJB
Starting with Seam 2.0.2.CR2 a special Weblogic specific jar has been packaged that does not contain the TimerServiceDispatcher . This is the only Seam EJB that uses variable arguments.
$SEAM_DIST/lib/interop/jboss-seam-wls-compatible.jar
To use this jar simply rename jboss-seam-wls-compatible.jar to jboss-seam.jar and replace the original in your applications EAR file.
We will be using this approach for the jee5/booking example here.
Weblogic's JSF support
Weblogic requires its own JSF 1.2 libraries be deployed when using an EAR based application. I suspect this has to do with classloader visibility while processing EARs and deploying EJBs.
Out of the box Weblogic does not come with its JSF libraries deployed, an like other parts of Weblogic it almost worked as expected.
- Start the Server and launch the Weblogic administration console.
- Deploy $BEA_HOME/wlserver_10.0/common/deployable-libraries/jsf-1.2.war
- Make sure
Install this deployment as a library
is selected - On the Settings for jsf(1.2,1.2.3.1) page set the Deployment Order to 99 so that it is deployed before autodeployed applications.
- Don't forget to activate your changes
Later you will see how to get your application to reference this shared library.
That should be it but you will get errors like the one below when deploying your application.
User defined listener com.sun.faces.config.ConfigureListener failed: java.lang.NullPointerException
Again this is most likely due to classloader visibility issues.. To work around this you need to have the jsf-api.jar from inside the jsf-1.2.war in the $DOMAIN_HOME/lib directory. While you are there you might as well copy in the $SEAM_DIST/lib/hsqldb.jar for the next section. You will need to stop and start your server for these to take effect.
Setting up the example data source
Configuring the seam-jee5-ds is pretty straight forward, and we can do it all through the admin console.
- If you have not already, you will need to copy the $SEAM_DIST/lib/hsqldb.jar into the $DOMAIN_HOME/lib directory and restart the server.
- Launch the admin console and navigate to $DOMAIN_NAME -> Services -> JDBC -> Data Sources
- Create a new data source with the values below.
- Name = seam-jee5-ds
- JNDI Name = seam-jee5-ds
- Set database type to other
- Database name = hsqldb
- Host Name = 127.0.0.1
- Port = 9001
- Username = sa
- Driver class = org.hsqldb.jdbc.Driver
- URL = jdbc:hsqldb:.
Then just choose your domain for the data source and activate your changes.
The example/jee5/booking example
Now Weblogic is all set up we need to make some adjustments to the jee5/booking example. These are mainly configuration file and build script changes.
Configuration File changes
Paths are assumed from the $SEAM_DIST/examples/jee5/booking directory
resources/META-INF/persistence.xml
- Comment out glassfish properties
- Set <jta-data-source>seam-jee5-ds</jta-data-source>
- Add the following properties:
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WeblogicTransactionManagerLookup"/>
resources/WEB-INF/web.xml
- Because the JSF jars are not going to be packaged in the WAR we need to add:
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
resources/META-INF/weblogic-application.xml
You must create this file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<weblogic-application>
<library-ref>
<library-name>jsf</library-name>
<specification-version>1.2</specification-version>
<implementation-version>1.2</implementation-version>
<exact-match>false</exact-match>
</library-ref>
<prefer-application-packages>
<package-name>antlr.*</package-name>
</prefer-application-packages>
</weblogic-application>
This allows the EAR to reference the JSF libraries installed above, and also manages a dependency conflict with antlr.
resources/WEB-INF/weblogic.xml
You must create this file:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app>
<library-ref>
<library-name>jsf</library-name>
<specification-version>1.2</specification-version>
<implementation-version>1.2</implementation-version>
<exact-match>false</exact-match>
</library-ref>
</weblogic-web-app>
This allows the WAR to reference the JSF libraries installed above and yes, it is needed in both places ;-)
resources/META-INF/ejb-jar.xml
Update the <assembly-descriptor> to look like the following:
<assembly-descriptor>
<interceptor-binding>
<ejb-name>AuthenticatorAction</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
<interceptor-binding>
<ejb-name>BookingListAction</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
<interceptor-binding>
<ejb-name>RegisterAction</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
<interceptor-binding>
<ejb-name>ChangePasswordAction</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
<interceptor-binding>
<ejb-name>HotelBookingAction</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
<interceptor-binding>
<ejb-name>HotelSearchingAction</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
<interceptor-binding>
<ejb-name>EjbSynchronizations</ejb-name>
<interceptor-class >org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
The changes to this file were the real challenge with Weblogic (to be polite about it). Unlike the other application servers tested Weblogic is only using a single instance of the sessionBeanInterceptor for all session beans if <ejb-name>*</ejb-name> is used. By defining a separate interceptor for each bean we force Weblogic to create a distinct instance for each session bean.
Note: There was a deployment descriptor that should have changed this behavior, but it did not have any effect.
Dependencies and getting them packaged
There are just a couple of changes needed the build file so that the new files above are packaged, and some extra jars are included.
build.xml
- Add the bits below:
<!-- jars to go in the war's lib -->
<fileset id="war.lib.extras" dir="${seam.dir}">
<include name="lib/richfaces-api.jar" />
</fileset>
<!-- Resources to go in the ear -->
<fileset id="ear.resources" dir="${resources.dir}">
<include name="META-INF/application.xml" />
<include name="META-INF/weblogic-application.xml" />
<include name="META-INF/*-service.xml" />
<include name="META-INF/*-xmbean.xml" />
<include name="treecache.xml" />
<include name="*.jpdl.xml" />
<exclude name=".gpd.*" />
<include name="*.cfg.xml" />
<include name="*.xsd" />
</fileset>
- Search for ear.lib.extras fileset and add these:
<include name="examples/wiki/lib/jboss-archive-browsing.jar" /> <include name="lib/concurrent.jar" />
$SEAM_DIST/lib/interop/jboss-seam-wls-compatible.jar
The last item to deal with is to replace the jboss-seam.jar with the jboss-seam-wls-compatible.jar. There are really two options.
- Backup the original $SEAM_DIST/lib/jboss-seam.jar and rename and replace with jboss-seam-wls-compatible.jar
- Modify the jboss-seam-jee5.ear after the build and replace the jar there.
Deploying and viewing your application
Now all we have to do build the application and deploy it.
If you chose the first option for handling the jboss-seam-wls-compatible.jar then all we need to do is execute:
$SEAM_DIST/examples/jee5/booking/ant
Then because we created our Weblogic domain in development mode we deploy it to the autodeploy directory.
cp $SEAM_DIST/examples/jee5/booking/dist/jboss-seam-jee5.ear $DOMAIN_HOME/autodeploy
Now point your browser at http://localhost:7001/seam-jee5/
If you see classdef or classloader issues during deployment or redeployment try removing the EAR from the autodeploy directory, restarting the server, and redeploying. Weblogic sometimes has classloader issues when applications are redeployed.
Would you like to know more?
See the reference guide chapter: Seam on BEA's Weblogic with details on this example and other Seam applications on Weblogic.
The 2.0.2.SP1 release addresses two issues that were found in the 2.0.2.GA release.
- [JBSEAM-2917] performance issues related to EjbDescriptor caching.
- [JBSEAM-3017] off-line seam-gen support.
We advise anyone who has installed 2.0.2.GA to upgrade to 2.0.2.SP1. There are no migration steps required as the changes were very targeted.
[Download] [Documentation] [Forums] [JIRA]
So you need to deploy to WebSphere, and you really want to take advantage of all the benefits of Seam including EJB3 - but your not sure where to begin?
You're in luck!!
This article along with the Seam Reference Guide WebSphere Integration Chapter should tell you everything you need to know. I'm going to get into some of the troubleshooting and debugging that went into that investigation and explain some of the parts that took a lot of time to figure out. I don't want to repeat the reference guide chapter word-for-word so I'll refer you to it at some points.
What You Need
WebSphere 6.1.X does not support EJB3/JPA out of the box, so you need to download the EJB3 feature pack listed above. WebSphere is a commercial product so you will either have to have a IBM account or download the trial version. Basic installation of WebSphere can also be a little tricky - so don't forget to augment the server profile you plan on using with the EJB3 features.
A really good network connection would also be helpful when downloading WebSphere and the feature pack. WebSphere itself is almost 500MB, and the feature pack is an amazing 750MB. That's 1.25GB of application server downloads- not sure where it all went exactly.
Special WebSphere setting
There are 2 special properties that need to be set for WebSphere to work well with any modern web application (especially JSF/AJAX apps). They are both custom web container properties (how to change).
These were both amazingly difficult to find, and the errors that are displayed do not make it obvious as to what the problem is.
prependSlashToResource = "true"
If you start to see a lot of exceptions like java.net.MalformedURLException: SRVE0238E: this property is probably not set. What was more annoying about this issue is that you need to track down the correct WebSphere error file in order to see the full exception. IBM is saying that they are spec compliant and every path must start with a /, that may be, but I've never had this problem anywhere else.
Even after you add this property you will still see a lot of warning Resource paths should have a leading slash but the resource will be returned as expected.
com.ibm.ws.webcontainer.invokefilterscompatibility = "true"
In most modern web applications resources like javascript, css, etc... are often served to the browser via dynamic requests. Most of these requests go through servlet filters for processing. With out this custom property you will see 404 FileNotFoundException for each resource retrieved this way. The tricky part was finding that out in the first place - because the symptom of this issue is seen as problems with css or javascript. So it looks like a RichFaces or JSF component incompatibility. Use something like firebug to look at each server request and you'll see what the real problem is.
The JEE5 booking example
So now that WebSphere settings are configured we can move on to actually getting our application working. All of the paths below assume that you in the examples/jee5/booking directory under your seam distribution.
Configuration file changes
Except for the web.xml file all the other configuration file changes are pretty basic.
resources/WEB-INF/web.xml
What needed to be done to this file was difficult to track down. The documentation for the EJB3 feature pack was hard to navigate and at some points contradicted itself. What it comes down to is that WebSphere EJB3 feature pack is not a full JEE5 implementation. One of the side effects of that is WebSphere does not support Servlet 2.5. So how are we going to reference EJB 3.0 beans? Good question - the answer is a little mucking around with the <ejb-local-ref> tags.
First things first though you need to adjust the top of the file to use Servlet 2.4. See the reference guide for details.
Now for the <ejb-local-ref> tags (here is just one of them). Notice that the <local-home> element is empty. This is the special sauce that tells WebSphere to make the correct bindings between the web module and the EJB3 beans. Without this it looks like everything is configured correctly and binding names in the logs appear to be correct, but your application won't be able to retrieve the beans.
<ejb-local-ref>
<ejb-ref-name>jboss-seam-jee5/AuthenticatorAction</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home></local-home>
<local>org.jboss.seam.example.booking.Authenticator</local>
</ejb-local-ref>
resources/META-INF/persistence.xml
See the reference guide for the full details, here is just some of the notable changes.
If your application is idle for about 10 minutes (WebSphere's default SFSB timeout) you may see a lot of exceptions like the one below:
com.ibm.wsspi.injectionengine.InjectionException:
EJBContext may only be looked up by or injected into an EJB
This is another limitation of the EJB3 Feature pack. Only EJBs support injection of the EJBContext. This means that when Seam/Hibernate attempt to handle clean-up of the transaction this exception is thrown. The solution is to tell hibernate not to flush transactions before completion. This can be done by either removing the property below or by setting it to false {th default is false
).
<property name="hibernate.transaction.flush_before_completion" value="false"/>
resources/import.sql
The default import.sql file needs to be overwritten with the one from the Seam JPA example. Either the Derby DB or the dialect does not support changes to the ID column. If you see errors related to the ID column it is probably this issue.
Other file changes
See the reference guide for the full details on changes needed for these files.
- resources/WEB-INF/components.xml
- resources/GlassfishDerbyDialect.class
Library changes
Manipulating required libraries is a pretty standard task when deploying applications from one application server to another. As with other parts of this document the details are in the reference guide (specific jars, modifications to the build.xml file, etc...).
- WebSphere 6.1 comes with their own version of JSF 1.1 (Seam requires JSF 1.2).
- During deployment through the administration console jar files in the root of EAR are not visible and may cause ClassCastExceptions.
- GlassfishDerbyDialect.class needs to be injected into the jboss-seam-jee5.jar because there is no place to put unarchived classes in the EAR.
Deploying the application
I like to sum up the deployment steps with this phrase:
Cool administration consoles are great as long as they are easy to understand and do what they say they will
The IBM administration console is very slick and looks good. It can do a lot of things, but when it came to deploying the EJB3 application it got a little confusing.
EAR file libraries
As mentioned above jar files at the base of the ear do not always seem to be available through the deployment mechanism of the console. This mean that we actually had two copied of jboss-seam.jar jar file. One at the EAR root, and one in the /lib directory.
Deployment options
Probably because the EJB3 feature pack is relatively new many of the deployment options were not well explained. This meant a lot of trial and error (along with a good dose of forum and support browsing). The results seem easy Deploy enterprise beans
check box must be selected (only if the EAR was not packaged by a WebSphere tool), and Allow EJB reference targets to resolve automatically
is required to have the EJB3 bindings work correctly with the modified web.xml from above.
Classloader setting not working
The Reference Guide talks about changes that are needed to the classloader settings of the application. This is to be expected, but when one of the options on the admin console does not seem to take effect no matter how you modify it, or how many times you restart it gets frustrating. Eventually I was able to find the file that the console was attempting to change, and I was able to change it manually (described in the guide). The path to the file was a little crazy and without really digging into the logs and directory structure you would not be able to get past this issue.
$WebSphereInstall/$yourServerName/profiles/$yourProfileName/config/cells/$yourCellName/applications/Seam Booking.ear/deployments/Seam Booking/deployment.xml
Classloader Viewer
One great feature of the console is the ClassLoader Viewer. In order to get this to work for a server profile you need to activate it in the profile settings. This allows you to view the classloader hierarchy and inspect classpaths, loaded classes, and what jars the classes came from. You can also search the whole tree with wild cards. This was very valuable when investigating various ClassCastExceptions and incompatible class errors.
Wrap-up
Seam applications deploy to WebSphere just fine, but the server is a little hard to manage and use without being a WebSphere expert. A few glaring things popped out as unexpected, but configuration and library file tweaking will almost certainly be a part of application deployments no matter what the platform.
For more examples and information on Seam integration with WebSphere and other application servers check out the Seam Getting Started Guide or the Seam Reference Guide
One of my first tasks since starting at JBoss/Red Hat was to investigate and document container interoperability. What I found is what I expected - various tweaks, settings and library requirements depending on what container is being deployed to. These have more to do with specific server needs rather than anything Seam is requiring (mostly).
Seam was designed to be container agnostic and run on any of the major application servers. Deploying any application to multiple application servers can have its share complications. This is usually due to variations in specification implementation, and special value add
features.
New Chapters
As of Seam 2.0.1.GA there are new reference guide chapters that cover specific servers and what is needed to get a Seam application running.
- IBM Websphere 6.1.0.13 + EJB3 FP [ 2.0.1.GA | 2.1.0.A1 ]
- BEA Weblogic 10.X [ 2.0.1.GA | 2.1.0.A1 ]
- Oracle OC4J 11g [ 2.0.1.GA | 2.1.0.A1 ]
Planned Chapters
It is not that Seam applications can't be deployed to these servers, its just that the reference guide chapter has not been finished. They either have existing information in the Seam documentation or other blogs, or have just not been written yet. The plan is finish these as time permits.
- Glassfish v2.X
- Tomcat 6.X (with and without JBoss embedded)
- JBoss AS 5.X
Chapter Format
All of these chapters follow the same basic format. First they discuss any installation or version requirements. Then modify and deploy the examples/jee5/booking example which uses EJB3 and EJB transactions. Then the examples/JPA example is examined and deployed. This uses POJO's for seam components and JPA for transactions. Then a seam-gen application is created, and modified for the given server.
You can keep up to date with issues related to Seam interoperability through the Seam Jira project.
Let us know if you run into any issues with this and I hope this is helpful.
|
|
|
Showing 51 to 54 of 54 blog entries |