2 Replies Latest reply on Jul 5, 2013 1:13 PM by rdiddly

    Confusion reigns

    rdiddly

      I am trying to move from EJB 2.1 to EJB 3.1 (and JBoss 4.2.2 to JBoss AS 7). I have posted numerous questions here, but it seems that either there's no one here to answer questions or I'm not asking the right questions, so I'll keep trying to formulate the right question.

       

      I have taken one of my SLSBs and gone through many different attempts to make it available to a helper class deployed in a war in the same ear as contains the ejb-jar that has the SLSB.

       

      My persistence.xml file is packaged in a jar file and deployed to the ear's lib folder.

       

      1) When I don't include markup in ejb-jar.xml declaring the ContentManagerBaan, I don't see any output from JBoss on startup to suggest that the Bean has been bound to JNDI, even though the Bean is declared with the @Stateless and @LocalBean annotations, so I define it in ejb-jar.xml. Using this strategy, I'm able to lookup the Bean from within the helper class packaged in the war.

       

      Here's the code and markup related to my issue:

       

      public interface ContentManagerBusiness {

                public Banner getTopNavBarBanner();

       

      }

       

      public class ContentManagerBeanBase implements ContentManagerBusiness {

                private static final Logger log = Logger.getLogger(ContentManagerBeanBase.class);

        @PersistenceContext(unitName="app")

        private EntityManager em;

       

        @Override

                public Banner getTopNavBarBanner() {

          Banner answer = null;

          try {

            Session hbmSession = (Session) em.getDelegate();

            Object o = hbmSession.getNamedQuery(Banner.NamedQuery.GetTopNavBarBanner.getQueryName())

                .setMaxResults(1)

                .uniqueResult();

            answer = (Banner) o;

          } catch (Exception e) {

            log.error("Failed getting content for topNavBar banner.", e);

          }

          return answer;

                }

       

      }

       

      @Stateless

      @LocalBean

      public class ContentManagerBean extends ContentManagerBeanBase {

       

      }

       

      persistence.xml:

       

        <persistence-unit name="app" transaction-type="JTA">
          
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
          
      <jta-data-source>java:/appDB</jta-data-source>
          
      <jar-file>../appEJB.jar</jar-file>
          
      <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
            
      <properties>
              
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
              
      <property name="hibernate.cache.use_second_level_cache" value="true" />                   
              
      <property name="hibernate.cache.use_query_cache" value="true" />
            
      </properties>
         
      </persistence-unit>

       

      ejb-jar.xml:

       

      <session>
          <ejb-name>ContentManager</ejb-name>
          <local>com.app.session.contentManager.ContentManagerLocal</local>
          <ejb-class>com.app.session.contentManager.ejb.ContentManagerBean</ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Container</transaction-type>
      </session>

       

      When my pom.xml declared the scope of the dependency on the ejb jar for the war's build as compile, I found that the ejb jar file was included in the war's lib folder. With this setup I was able to run the code to the point where I had a ClassCastException in the ContentManagerBean when attempting to cast the return of the uniqueResult call to an instance of Banner. This appeared to be a classloader problem, and I thought it made no sense to include the ejb jar in the war's lib folder if it was being deployed as part of the ear, so I changed the scope of the dependency to provided. This removed the ejb jar from the war's lib folder, leaving me with a single definition of the Banner class. (The Banner class is a model class, mapped by a hbm.xml descriptor. The class is defined in the ejb's jar.)

       

      2) After removing the ejb jar from the war's lib folder, I find that the PersistenceContext declared in the ContentManagerBusinessBase is null at run time.

       

      I hope that someone can shed some light on what it is I'm doing wrong with the information I've provided. Short of that, I hope that someone will ask me to provide some additional information, or give me a clue as to what I should look at. I am using Oracle's online docs on JEE 6 and O'Reilly's Enterprise JavaBeans 3.1 and searches all over the internet, but so far have had no luck figuring out what I'm doing wrong.

       

      Thanks in advance.

        • 1. Re: Confusion reigns
          rdiddly

          Frustrated with a dearth of suggestions from the community, I decided yesterday to start from scratch and see if I could get my bean to work without all of the other baggage represented by my application. Much to my surprise, I have it working. I got rid of the declaration of the bean in ejb-jar.xml, used @Stateless in the definition, deployed it with the same packaging mechanism, and was able to access it from a bare-bones test servlet. Its PersistenceContext had been established when the getTopNavBarBanner() method was invoked, and it was able to execute the query defined in the hbm.xml file and retrieve an instance of a Banner and return it with no ClassCastException.

           

          Now I have to try to find out what is different about my test scenario (besides the baggage) that allows this to work.

          • 2. Re: Confusion reigns
            rdiddly

            Going one step further, I went back to my "legacy" code and removed all ejb-local-ref blocks from both web.xml files, removed the ejb-jar.xml and jboss.xml from the ejb jar build, basically, anything that wasn't being generated for me by Maven in my test environment (except for what I knew I absolutely needed). Some of what I removed was clearly no longer needed. The end result was that I was able to get to my ContentManagerBean and it had its EntityManager established, and it was able to execute its query and return a valid result. So, it looks like I know how to do this now. Just a matter of making similar changes to the rest of the session beans in my app. I seem to be on my way. I hope this post helps someone else in a similar circumstance (assuming anyone else out there hasn't done this all long ago).