0 Replies Latest reply on Dec 8, 2011 6:24 PM by Rafal Krzewski

    Using Seam 2.2 in EAR with multiple EJB modules with JBoss 7

    Rafal Krzewski Newbie

      Hi,


      I am trying to get my head around an application that I've inherited from another team. It is currently running on JBoss 4.3.2 and I was given a tarball with JBoss runtime that was tweaked to work with the application, but nobody can tell my how and why. The application's EAR is a kitchen sink full of JARs, Maven POMs are a mess... you get the picture. In order to mitigate long term risk I am picking the application apart to see what is actually in there, how stuff work and which pieces are cruft picked up along the way that can be safely dropped. In the process I decided to port the application to JBoss 7, because I am very impressed with it. I know that this will force me to jump through additional hoops, but the faster turnaround and smaller footprint of the server should compensate for that in the longer perspective.


      I came across a problem with Seam that took a while to unravel, but my solution is not very elegant, so I'm turning to the experts for advice - perhaps there's a better way?


      The application EAR contains two EJB modules and a WAR and it uses Seam 2.2 to wire the EJBs and JSFs together.


      When running in JBoss 7 each EJB is bound under a few JNDI names. For example a hypothetical SLSB com.acme.gizmoapp.business.foo.FooManagerImpl, that has @Local interface com.acme.gizmoapp.business.foo.FooManager would be bound as:


              java:global/gizmoapp/business/FooManagerImpl!com.acme.gizmoapp.business.foo.FooManager
              java:app/business/FooManagerImpl!com.acme.gizmoapp.business.foo.FooManager
              java:module/FooManagerImpl!com.acme.gizmoapp.business.foo.FooManager
              java:global/gizmoapp/business/FooManagerImpl
              java:app/business/FooManagerImpl
              java:module/FooManagerImpl


      I've read the docs about how global/ app/ and module/ scopes work, and I appreciate the design.


      com.acme.gizmoapp.business.foo.FooManagerImpl is anotated with Seam annotation @Name("fooManager") and other Seam components refer to it using this name.


      The application's WAR module was /WEB-INF/components.xml that contains the following bit:


      <core:init jndi-pattern="gizmoapp/#{ejbName}/local"/>



      That was the Seam component name to EJB JNDI name that worked with JBoss 4. It does not work any longer with JBoss 7, and component access fails with NameNotFound exceptions.


      Moreover, after a bit of tweaking I came to the conclusion that I cannot configure it correctly using jndi-prefix:


      <core:init jndi-pattern="java:module/#{ejbName}"/>



      does not work because the binding is visible only within the same EJB module and hence business EJBs cannot access dao EJBs


      <core:init jndi-pattern="java:app/dao/#{ejbName}"/>



      would work for the dao module, but wouldn't work for business module, and JSFs wouldn't be able to find business EJBs...


      I would have to specify something along the lines of:


      <core:init jndi-pattern="java:app/#{ejbModule}/#{ejbName}">



      but unfortunately that does not work.


      It would be nice to be able to define the jndi-pattern on per-module basis, but I quickly learned that placing /WEB-INF/components.xml is not a good idea. Also, I couldn't find any information abount providing per-module configuration from seam.properties file - as far as I understand it, seam.properties is acting only as a marker in every module except the master one.


      There is one more way of solving this - explicitly defining the JNDI name for each Seam component. In case our hypothetical fooManager:


              @Stateless
              @Name("fooManager")
              @JndiName("java:app/business/FooManagerImpl")
              public class FooManagerImpl implements FooManager, Serializable



      This needs to be done for about 100 beans in the application, so I'll probably hack together a little script that will do that automatically using regular expressions.


      If there is a better / easier way I'm all ears :)


      Thanks,


      Rafał