2 Replies Latest reply on Feb 19, 2010 12:51 PM by viktor0815

    Seam app not working in Tomcat with an Embedded JBoss

    viktor0815

      Hi everybody,


      we cannot get our Seam app running when we deploy it in Tomcat with an Embedded JBoss.  The app works fine when we run our integration tests.


      Configuration:



      • Apache Tomcat 6.0.20

      • JBoss Embedded Beta 3

      • Seam 2.2.0 GA



      There are two errors:



      • EntityManagers are not injected into the Dao bean.

      • When we access the web app root URL, Tomcat throws an exception: Caused by: javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.NameNotFoundException: Name java:comp is not bound in this Context]




      components.xml


      ?xml version="1.0" encoding="UTF-8"?>
      <components xmlns="http://jboss.com/products/seam/components" ...>
      
        <core:init debug="true" jndi-pattern="@jndiPattern@"/>
      
        <core:manager 
          conversation-timeout="120000"
          concurrent-request-timeout="500" 
          conversation-id-parameter="cid" />
      
        <security:identity authenticate-method="#{authenticator.authenticate}" />
        
        <persistence:managed-persistence-context
          name="epaperEntityManager" 
          auto-create="true"
          entity-manager-factory="java:/EntityManagerFactories/epaper"
          />
      
        <persistence:managed-persistence-context
          name="spiderEntityManager" 
          auto-create="true"
          entity-manager-factory="java:/EntityManagerFactories/spider"
          />
      
        <core:resource-loader>
          <core:bundle-names>
            <value>epaper_messages</value>
            <value>standard_messages</value>
          </core:bundle-names>
        </core:resource-loader>
      
        <web:ajax4jsf-filter url-pattern="*.faces" />
      
        <drools:rule-base name="securityRules">
          <drools:rule-files>
            <value>/security.drl</value>
          </drools:rule-files>
        </drools:rule-base>
      
        <security:rule-based-permission-resolver
          security-rules="#{securityRules}" />
      
        <security:identity authenticate-method="#{authenticator.authenticate}"
          remember-me="true" />
      
        <event type="org.jboss.seam.security.notLoggedIn">
          <action execute="#{redirect.captureCurrentView}" />
        </event>
        <event type="org.jboss.seam.security.loginSuccessful">
          <action execute="#{redirect.returnToCapturedView}" />
        </event>
      
        <async:quartz-dispatcher />
      
      </components>
      



      components.properties:


      jndiPattern=\#{ejbName}/local
      embeddedEjb=true
      



      persistence.xml:


      <?xml version="1.0" encoding="UTF-8"?>
      <persistence xmlns="http://java.sun.com/xml/ns/persistence" ...>
        <persistence-unit name="epaper" transaction-type="JTA">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <jta-data-source>java:/epaperDs</jta-data-source>
          <class>...</class>
          <properties>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/epaper" />
            <property name="hibernate.connection.username" value="..." />
            <property name="hibernate.connection.password" value="..." />
            <property name="jboss.entity.manager.factory.jndi.name"
              value="java:/EntityManagerFactories/epaper" />
            <property name="hibernate.transaction.manager_lookup_class"
              value="org.hibernate.transaction.JBossTransactionManagerLookup" />
          </properties>
        </persistence-unit>
      
        <persistence-unit name="spider" transaction-type="JTA">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <jta-data-source>java:/spiderDs</jta-data-source>
          <class>...</class>
          <exclude-unlisted-classes />
          <properties>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/spider" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.connection.username" value="..." />
            <property name="hibernate.connection.password" value="..." />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
            <property name="jboss.entity.manager.factory.jndi.name"
              value="java:/EntityManagerFactories/spider" />
            <property name="hibernate.transaction.manager_lookup_class"
              value="org.hibernate.transaction.JBossTransactionManagerLookup" />
          </properties>
        </persistence-unit>
      
      </persistence>
      



      persistence.properties:


      hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
      hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
      hibernate.jndi.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
      hibernate.jndi.java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
      hibernate.bytecode.use_reflection_optimizer=false
      hibernate.bytecode.provider=javassist
      



      Dao class:


      @Stateless
      @Name("dao")
      @JndiName("Dao/local")
      @AutoCreate
      public class Dao implements EpaperDao {
          
          @PersistenceContext(unitName="epaper")
          private EntityManager epaperEntityManager;
          
          @PersistenceContext(unitName="spider")
          private EntityManager spiderEntityManager;
      
          ...
      



      Both entity managers are injected by Seam when we use this class in our integration tests.  The class is also picked up by the EJB3 container:


      INFO  [org.jboss.ejb3.MCKernelAbstraction] installing bean: jboss.j2ee:jar=classes,name=Dao,service=EJB3 with dependencies:
      INFO  [org.jboss.ejb3.MCKernelAbstraction]   and supplies:
      INFO  [org.jboss.ejb3.MCKernelAbstraction]      Class:i2.dnb.epaper.db.EpaperDao
      INFO  [org.jboss.ejb3.EJBContainer] STARTED EJB: i2.dnb.epaper.db.Dao ejbName: Dao
      



      However when the app is started inside the container both Entity Managers are null.


      When we go to the webapp root URL, the container spews a ton of exceptions which I've attached at the end.


      First the warnings the we during startup in case they are related:


      log4j:ERROR A "org.jboss.logging.util.OnlyOnceErrorHandler" object is not assignable to a "org.apache.log4j.spi.ErrorHandler" variable.
      log4j:ERROR The class "org.apache.log4j.spi.ErrorHandler" was loaded by 
      log4j:ERROR [WebappClassLoader
        delegate: false
        repositories:
          /WEB-INF/classes/
      ----------> Parent Classloader:
      org.apache.catalina.loader.StandardClassLoader@443226
      ] whereas object of type 
      log4j:ERROR "org.jboss.logging.util.OnlyOnceErrorHandler" was loaded by [org.apache.catalina.loader.StandardClassLoader@443226].
      WARN  [org.jboss.ejb3.timerservice.jboss.JBossTimerServiceFactory] TIMER SERVICE IS NOT INSTALLED
      ...
      INFO  [org.hibernate.ejb.Ejb3Configuration] Processing PersistenceUnitInfo [
           name: epaper
           ...]
      WARN  [org.hibernate.ejb.Ejb3Configuration] Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null.
      ...
      INFO  [org.hibernate.impl.SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:jar=classes.jar,unitName=epaper
      WARN  [org.hibernate.impl.SessionFactoryObjectFactory] InitialContext did not implement EventContext
      ...
      WARN  [org.jboss.ejb3.timerservice.jboss.JBossTimerServiceFactory] TIMER SERVICE IS NOT INSTALLED
      ...
      WARN  [org.jboss.seam.security.permission.PersistentPermissionResolver] no permission store available - please install a PermissionStore with the name 'org.jboss.seam.security.jpaPermissionStore' if persistent permissions are required.
      ...
      



      The exception after accessing the root URL follows.


      ERROR [org.jboss.seam.jsf.SeamPhaseListener] swallowing exception
      java.lang.RuntimeException: exception invoking: getTransaction
           at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:154)
           at org.jboss.seam.Component.callComponentMethod(Component.java:2249)
           at org.jboss.seam.Component.unwrap(Component.java:2275)
           at org.jboss.seam.Component.getInstance(Component.java:2041)
           at org.jboss.seam.Component.getInstance(Component.java:2000)
           at org.jboss.seam.Component.getInstance(Component.java:1994)
           at org.jboss.seam.Component.getInstance(Component.java:1967)
           at org.jboss.seam.Component.getInstance(Component.java:1962)
           at org.jboss.seam.transaction.Transaction.instance(Transaction.java:39)
           at org.jboss.seam.jsf.SeamPhaseListener.handleTransactionsBeforePhase(SeamPhaseListener.java:321)
           at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseListener.java:144)
           at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:118)
           at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:214)
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:96)
           at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:103)
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
           at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
           at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
           at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
           at java.lang.Thread.run(Thread.java:619)
      Caused by: javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.NameNotFoundException: Name java:comp is not bound in this Context]
           at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1254)
           at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:741)
           at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:629)
           at javax.naming.InitialContext.lookup(InitialContext.java:392)
           at org.jboss.seam.util.EJB.getEJBContext(EJB.java:85)
           at org.jboss.seam.transaction.Transaction.createCMTTransaction(Transaction.java:69)
           at org.jboss.seam.transaction.Transaction.getTransaction(Transaction.java:53)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:597)
           at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
           at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
           ... 46 more
      Caused by: javax.naming.NameNotFoundException: Name java:comp is not bound in this Context
           at org.apache.naming.NamingContext.lookup(NamingContext.java:770)
           at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
           at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137)
           at org.jboss.embedded.tomcat.jndi.ENCFactory.getObjectInstance(ENCFactory.java:74)
           at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
           at org.jnp.interfaces.NamingContext.getObjectInstance(NamingContext.java:1312)
           at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure(NamingContext.java:1329)
           at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:765)
           at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:629)
           at javax.naming.InitialContext.lookup(InitialContext.java:392)
           at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1250)
           ... 58 more
      WARN  [org.jboss.seam.jsf.SeamPhaseListener] uncaught exception, passing to exception handler
      java.lang.IllegalStateException: Could not commit transaction
           at org.jboss.seam.jsf.SeamPhaseListener.commitOrRollback(SeamPhaseListener.java:625)
           at org.jboss.seam.jsf.SeamPhaseListener.commitOrRollback(SeamPhaseListener.java:604)
           at org.jboss.seam.jsf.SeamPhaseListener.handleTransactionsAfterPhase(SeamPhaseListener.java:345)
           at org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:245)
           at org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:196)
           at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:175)
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:114)
           at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:103)
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
           at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
           at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
           at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
           at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
           at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
           at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
           at java.lang.Thread.run(Thread.java:619)
      


        • 1. Re: Seam app not working in Tomcat with an Embedded JBoss
          viktor0815

          I realized that I can get rid of the acception when accessing the URL by adding the following to components.xml:


            <core:init transaction-management-enabled="false" />
          
            <transaction:no-transaction />
          



          I understand that this disables Seam transactions accross Faces requests.  I have not yet tried to create an exception myself because the EntityManagers are still null.

          • 2. Re: Seam app not working in Tomcat with an Embedded JBoss
            viktor0815

            The problem was a duplicate persistence-api.jar in my WEB-INF/lib directory.


            FWIW, here's how I found the culprit of the problem.


            I added the PersistenceContextValidator descripped in the book Seam in Action on page 369.  Basically this tries a JNDI-lookup on the configured name like this: A

            ValueExpression<EntityManager> entityManager

            is set to
            #{epaperEntityManager}

            via components.xml, see above. 
            entityManager.getValue()

            then performs a JNDI lookup.


            After changing the exception (which is completely swallowed by Tomcat, resulting in a deployment failure with no indication as to what went wrong -- WTF?) to a log message, I was treated to the following error:


            java.lang.ClassCastException: org.jboss.ejb3.entity.InjectedEntityManagerFactory
               cannot be cast to javax.persistence.EntityManagerFactory



            This can't be right, but it points to a class loader error.  For a cast to succeed both classes have to be loaded by the same class loader.  The duplicate persistence-api.jar prevented that.