5 Replies Latest reply on Dec 3, 2008 3:57 PM by dan.j.allen

    automatic loading of persistence units in JBoss AS 5

    dan.j.allen

      One of the changes in JBoss AS 5 that comes as a surprise for many Seam developers/users familiar with the behavior of JBoss AS 4 is the automatic loading of persistence units from /META-INF/persistence.xml. (As expected, we had to change several of the Seam examples to accommodate this change). This is one of those configuration by exception features in Java EE 5, with one significant exception. While the container will locate the /META-INF/persistence.xml file on its own, a container that goes by the book will only deploy the persistence unit if a resource reference is declared in a descriptor file (web.xml or ejb-jar.xml) or annotation (@PersistenceUnit or @PersistenceContext). JBoss AS does not wait for this signal.

      In my opinion, there is a problem with the JBoss AS approach. What if you have persistence units that you don't want to deploy? One use case is that you have persistence units for different environments and a configuration file can toggle between them. Another use case is that you have another library, such as Spring or Seam, which bootstraps the persistence unit instead. Sure, you could rename the file, but then you break all the IDE behavior that expects the file to be named persistence.xml. Personally, I think there should be some way to disable the behavior in JBoss AS and make it look for the persistence unit references. I agree to keep the automatic loading as the default, but it is pretty inconvenient not to be able to disable it.

      Anyone else agree? Disagree? Why?

        • 1. Re: automatic loading of persistence units in JBoss AS 5
          dan.j.allen

          I believe there are cases when it's not just as easy as just taking the persistence unit out of the persistence.xml file. For instance, if you want Seam or Spring to bootstrap the persistence unit instead of the Java EE container, you are in a bit of a fix, especially if you plan to use the Java SE standard way of loading the persistence unit (you can obviously go around it like Spring does and load a file with a different name). Also, what you gain by convention (loading all persistence units in persistence.xml) you lose in build complexity. For instance, Hibernate Tools allows you to have multiple persistence units defined in persistence.xml which you can use for testing queries, but then you have to expunge those in your build logic before deploying. Definitely worth doing for a production build, but not something to worry about early on in development.

          All I'm saying is that I can anticipate plenty of scenarios where I will need to disable this automatic loading of persistence units (or selective loading) and I don't know how to do that in JBoss AS 5. I'm willing to say that the default behavior is what we want, but I strongly believe that control over this mechanism needs to be documented.

          • 2. Re: automatic loading of persistence units in JBoss AS 5
            dan.j.allen

            According to Ales, these are the current ways to control this behavior:

            By order of severity:
            1) remove or replace deployer that adds this behavior
            - writing new MC deployers is trivial
            2) add new deployer that alters this behavior
            - MC deployers are metadata driven chain
            3) add new structure deployer
            - e.g. custom Seam structure
            4) limit where persistence.xml is valid (see jboss-structure.xml)
            - https://www.jboss.org/community/docs/DOC-13178
            5) rename files: persistence.xml --> persistence-xyz.xml

            If this kicks in via @PersistenceContext:
            1) limit scanning (as I already posted in JIRA):
            - https://www.jboss.org/community/docs/DOC-13178 (see jboss-scanning.xml)

            • 3. Re: automatic loading of persistence units in JBoss AS 5
              dan.j.allen

              To see this problem in action in a Seam example, follow these steps:

              svn co http://anonsvn.jboss.org/repos/seam/trunk
              ant build
              set jboss.home in build.properties to point to an JBoss AS 5 installation
              cd examples/spring
              ant jbosswar
              watch for failed deployment in the log files:

              java.lang.IllegalArgumentException: Can't find a persistence unit
              named 'null' in
              AbstractVFSDeploymentContext@15139323{vfszip:/home/dallen/opt/jboss-as-5.0.0.preGA/server/default/deploy/jboss-seam-spring.war}
              at org.jboss.jpa.resolvers.DefaultPersistenceUnitDependencyResolver.resolvePersistenceUnitSupplier(DefaultPersistenceUnitDependencyResolver.java:141)
              at org.jboss.web.tomcat.service.TomcatInjectionContainer.resolvePersistenceUnitSupplier(TomcatInjectionContainer.java:676)
              at org.jboss.injection.PersistenceUnitHandler.addPUDependency(PersistenceUnitHandler.java:123)
              at org.jboss.injection.PersistenceContextHandler.loadXml(PersistenceContextHandler.java:76)
              at org.jboss.web.tomcat.service.TomcatInjectionContainer.processMetadata(TomcatInjectionContainer.java:544)

              • 4. Re: automatic loading of persistence units in JBoss AS 5
                alesj

                Adding empty jboss-scanning.xml results in this:

                21:23:57,312 ERROR [[/jboss-seam-spring]] Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener
                java.lang.IllegalStateException: Two components with the same name and precedence - component name: org.jboss.seam.ui.entityLoader, component classes: org.jboss.seam.ui.JpaEntityLoader, org.jboss.seam.ui.converter.entityConverter.EntityLoader
                 at org.jboss.seam.init.Initialization.addComponentDescriptor(Initialization.java:596)
                 at org.jboss.seam.init.Initialization.installScannedComponentAndRoles(Initialization.java:950)
                 at org.jboss.seam.init.Initialization.scanForComponents(Initialization.java:890)
                 at org.jboss.seam.init.Initialization.init(Initialization.java:701)
                 at org.jboss.seam.servlet.SeamListener.contextInitialized(SeamListener.java:34)
                 at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3910)


                Known issue?

                • 5. Re: automatic loading of persistence units in JBoss AS 5
                  dan.j.allen

                  It appears that you have dead files remaining in your source tree that you used to build Seam (or you have different versions of Seam on the classpath). You can see that the second component was removed a couple months ago in a package restructuring.

                  http://fisheye.jboss.com/browse/Seam/trunk/ui/src/main/java/org/jboss/seam/ui/converter/entityConverter/EntityLoader.java