This time I would like to guide you through migration of Seam Booking example which is Enterprise application - EAR.

 

Seam EAR migration is a little complicated in comparing to Seam JPA example. But what we have learnt from JPA example migration, we can use also in this EAR migration.

 

Basic overview of migration steps:

# Initialization of JSF 1.2 instead of default JSF 2,

# Bundling older hibernate jars than what are provided in JBoss AS7 by default,

# Changes in JNDI bindings  due new [Java EE 6 JNDI portable syntax|http://download.oracle.com/javaee/6/tutorial/doc/gipjf.html#girgn]. (Note: there is a little mistake in that tutorial - see [JAVAEETUTORIAL-44|http://java.net/jira/browse/JAVAEETUTORIAL-44]

 

First 2 steps we've done already in [JPA example migration|http://community.jboss.org/blogs/marek-novotny/2011/07/15/seam-2-jpa-example-on-jboss-as7], but third step is new one because of using EJBs in EAR.

 

So let's start:

 

# Add new file jboss-deployment-structure.xml with the following content into _jboss-seam-booking.ear/META-INF/_:{code:xml}

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">

  <deployment>

        <dependencies>

          <module name="org.apache.log4j" export="true"/>

          <module name="org.dom4j" export="true"/>

          <module name="org.apache.commons.logging" export="true"/>

          <module name="org.apache.commons.collections" export="true"/>

          <module name="javax.faces.api" slot="1.2" export="true"/>

          <module name="com.sun.jsf-impl" slot="1.2" export="true"/>

        </dependencies>

  </deployment>

  <sub-deployment name="booking-web.war">

      <exclusions>

          <module name="javax.faces.api" slot="main"/>

          <module name="com.sun.jsf-impl" slot="main"/>

        </exclusions>

        <dependencies>

          <module name="javax.faces.api" slot="1.2"/>

          <module name="com.sun.jsf-impl" slot="1.2"/>

        </dependencies>

  </sub-deployment>

</jboss-deployment-structure>

{code}

# Next remove/comment hibernate property for cache provider class in jboss-seam-booking.jar/META-INF/persistence.xml:

{code:xml}

<!-- <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/> -->

{code}

# Add the following dependencies from seam distribution (seam/lib directory) into jboss-seam-booking.ear/lib directory, which are in JBoss AS 5/6 in different versions:{noformat}slf4j-api.jar

slf4j-log4j12.jar

hibernate-core.jar

hibernate-entitymanager.jar

hibernate-validator.jar

hibernate-annotations.jar

hibernate-commons-annotations.jar{noformat}

# Next we need to change JNDI lookup strings in jboss-seam-booking.war/WEB--INF/components.xml. Because of new JNDI portable rules, AS7 now binds EJBs with JNDI portable rules like for instance:

{noformat}

java:global/seam-booking/booking-ejb/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching

java:app/booking-ejb/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching

java:module/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching

java:global/seam-booking/booking-ejb/HotelSearchingAction

java:app/booking-ejb/HotelSearchingAction

java:module/HotelSearchingAction

{noformat} and for Seam framework EJBs like for instance:

{noformat}

java:global/seam-booking/jboss-seam/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations

java:app/jboss-seam/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations

java:module/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations

java:global/seam-booking/jboss-seam/EjbSynchronizations

java:app/jboss-seam/EjbSynchronizations

java:module/EjbSynchronizations

{noformat}

Notice difference between _java:app/jboss-seam/EjbSynchronizations_ and _java:app/booking-ejb/HotelSearchingAction_.

We can't use the single jndiPattern like we did before in JBoss AS 5/6. So there are a few solutions to do it, I chose adding jndi-name for every EJB into WEB-INF/components.xml:

{code:xml}

<component class="org.jboss.seam.transaction.EjbSynchronizations" jndi-name="java:app/jboss-seam/EjbSynchronizations"/>

<component class="org.jboss.seam.async.TimerServiceDispatcher" jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>

<component class="org.jboss.seam.example.booking.AuthenticatorAction" jndi-name="java:app/booking-ejb/AuthenticatorAction" />

<component class="org.jboss.seam.example.booking.BookingListAction"  jndi-name="java:app/booking-ejb/BookingListAction" />

<component class="org.jboss.seam.example.booking.RegisterAction" jndi-name="java:app/booking-ejb/RegisterAction" />

<component class="org.jboss.seam.example.booking.HotelSearchingAction" jndi-name="java:app/booking-ejb/HotelSearchingAction" />

<component class="org.jboss.seam.example.booking.HotelBookingAction" jndi-name="java:app/booking-ejb/HotelBookingAction" />

<component class="org.jboss.seam.example.booking.ChangePasswordAction" jndi-name="java:app/booking-ejb/ChangePasswordAction" />

{code}

You can alternatively add @JNDIName(value="") annotation with JNDI path. Example of changed SLSB is below, look at _@JndiName_ annotation, detailed description is at Seam2 reference documentation:

{code:java}

@Stateless

@Name("authenticator")

@JndiName(value="java:app/booking-ejb/AuthenticatorAction")

public class AuthenticatorAction

    implements Authenticator

{

...

}

{code}

 

That is all in Booking example modifications.

 

Unfortunatelly the example how is done will deploy with error in JSF initialization.

{noformat}

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-1) Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener: com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! org.jboss.seam.jsf.SeamApplicationFactory

        at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:215) [jsf-impl-1.2_13.jar:1.2_13-b01-FCS]

        at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:196) [jsf-impl-1.2_13.jar:1.2_13-b01-FCS]

        at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3368) [jbossweb-7.0.0.CR4.jar:7.0.0.Final]

        at org.apache.catalina.core.StandardContext.start(StandardContext.java:3821) [jbossweb-7.0.0.CR4.jar:7.0.0.Final]

        at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:70) [jboss-as-web-7.0.0.Final.jar:7.0.0.Final]

        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1765)

        at org.jboss.msc.service.ServiceControllerImpl$ClearTCCLTask.run(ServiceControllerImpl.java:2291)

        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [:1.6.0_26]

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [:1.6.0_26]

        at java.lang.Thread.run(Thread.java:662) [:1.6.0_26]

Caused by: java.lang.InstantiationException: org.jboss.seam.jsf.SeamApplicationFactory

        at java.lang.Class.newInstance0(Class.java:340) [:1.6.0_26]

        at java.lang.Class.newInstance(Class.java:308) [:1.6.0_26]

        at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:537) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]

        at javax.faces.FactoryFinder.getImplementationInstance(FactoryFinder.java:405) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]

        at javax.faces.FactoryFinder.access$400(FactoryFinder.java:135) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]

        at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:717) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]

        at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:239) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]

        at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:186) [jsf-impl-1.2_13.jar:1.2_13-b01-FCS]

        at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:131) [jsf-impl-1.2_13.jar:1.2_13-b01-FCS]

        at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:205) [jsf-impl-1.2_13.jar:1.2_13-b01-FCS]

{noformat}

 

This is a bug in AS 7 Final. But I don't write this blog if there is not a way how to work around it ;-).

I discussed the issue with AS 7 developers and they fixed it in upstream sources.

So we need to download AS7 snapshot or build AS 7 from git sources. The easier is to get working binaries at [latest JBoss AS7 snapshot|http://hudson.jboss.org/jenkins/view/JBoss AS/job/JBoss-AS-7.0.x/lastSuccessfulBuild/artifact/build/target/jboss-7.0.x.zip]

 

And that is realy all!