3 Replies Latest reply on May 7, 2009 5:31 PM by Arbi Sookazian

    EJB Seam beans on Glassfish doesn't work for me

    Larry Ozo Newbie

      Hi I have crearted my first seam project but it doen't work on glassfish v2ur2


      in ear application
      ejb module:


      
      @Stateless
      @Name("ejbbean")
      public class EjbBean implements EjbBeanLocal {
          
          public String getStr(){
              return "It works!";
          }
       
      }
      @Local
      public interface EjbBeanLocal {
      
          public java.lang.String getStr();
          
      }
      



      web mobule just one jsf page


      
       <h:outputText value="#{ejbbean.str}" />
      
      



      threw exception:
      javax.servlet.ServletException: Could not instantiate Seam component: ejbbean


      root error:
      Caused by: java.lang.ClassNotFoundException: ejb.EjbBeanLocal


      my components.xml


      
      <components xmlns="http://jboss.com/products/seam/components"
               xmlns:core="http://jboss.com/products/seam/core">
      
           <core:init jndi-pattern="java:comp/env/#{ejbName}" debug="true" precedence="100" />
      </components>
      
      
      
      



      web xml local ref:


      
          <ejb-local-ref>
              <ejb-ref-name>EjbBean</ejb-ref-name>
              <ejb-ref-type>Session</ejb-ref-type>
              <local>ejb.EjbBeanLocal</local>
          </ejb-local-ref>
      
      



      I have checked ejb obtain with JNDI look up - it works well.


      
      @Name("warbean")
      public class WarBean {
      
          
        //  @In(value="ejbbean",required=false,create=true)  <-- this doesn't work
          private EjbBeanLocal my;
      
          public String getStr(){
              my = lookupEjbBean(); <-- this works well
              return my.getStr();
          }
      
          private EjbBeanLocal lookupEjbBean() {
              try {
                  Context c = new InitialContext();
                  return (EjbBeanLocal) c.lookup("java:comp/env/EjbBean");
              } catch (NamingException ne) {
                  Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
                  throw new RuntimeException(ne);
              }
          }
      }
      
      


        • 1. Re: EJB Seam beans on Glassfish doesn't work for me
          Arbi Sookazian Master

          Unless you want to learn the ins-and-outs of Seam configuration the hard way (trial-and-error), I recommend you use seam-gen to create a project skeleton.  It's fast and easy and helpful.


          In any event, in EJB3/Seam, we don't need (or like :) to use JNDI lookup.  Rather, we prefer to use DI (dependency injection).  Perhaps you already know this but were just testing/trouble-shooting the binding/lookup problem.


          So in your WarBean JavaBean Seam component, the following SLSB injection is correct:


          @In(value="ejbbean",required=false,create=true)  
          private EjbBeanLocal my;



          typically, I would do it this way:


          @In(required=false,create=true)  
          private EjbBeanLocal ejbbean;



          The problem is the following:


          <core:init jndi-pattern="java:comp/env/#{ejbName}" debug="true" precedence="100" />



          Try this (assuming your project name is 'foo', so replace foo with your project name):


          <core:init jndi-pattern="foo/#{ejbName}/local" debug="true" precedence="100" />



          Remove the following from web.xml:


            <ejb-local-ref>
                  <ejb-ref-name>EjbBean</ejb-ref-name>
                  <ejb-ref-type>Session</ejb-ref-type>
                  <local>ejb.EjbBeanLocal</local>
              </ejb-local-ref>
          



          The above does not belong in web.xml (servlet deployment descriptor), it may be placed in ejb-jar.xml (ejb deployment descriptor) but is not required b/c we use annotations for most metadata markup in EJB3.  As per JSR220, if you do use metadata in ejb-jar.xml, then it overrides whatever EJB-related annotations you have in your files.


          If you have further questions on how to set this up, look at the booking example in the Seam distro.

          • 2. Re: EJB Seam beans on Glassfish doesn't work for me
            Larry Ozo Newbie
            Arbi! Thanks! I have fixed this! there was an another copy of jboss-seam.jar in my Glassfish domain lib directory. When I have removed it from domain libs - the project start work well.

            P.S.
            jndi pattern for glassfish must be "java:comp/env/#{ejbName}"

            foo/#{ejbName}/local - it is for jboss AS

            ejb-local-ref is required in glassfish. otherwise you can not obtain ejb with jndi lookup
            • 3. Re: EJB Seam beans on Glassfish doesn't work for me
              Arbi Sookazian Master

              Larry Ozo wrote on May 07, 2009 09:34:


              Arbi! Thanks! I have fixed this! there was an another copy of jboss-seam.jar in my Glassfish domain lib directory. When I have removed it from domain libs - the project start work well.

              P.S.
              jndi pattern for glassfish must be java:comp/env/#{ejbName}

              foo/

              1. {ejbName}/local - it is for jboss AS



              ejb-local-ref is required in glassfish. otherwise you can not obtain ejb with jndi lookup



              glad you fixed it.  sorry, I don't have experience with Seam + Glassfish, I just learned something new...


              so does the ejb-local-ref metadata belong in the web.xml or ejb-jar.xml?


              aha, I just answered my question in the Seam 2.1.x ref docs:



              29.1.5. Integrating Seam with your EJB container




              There are two places you have to define the EJB reference when using Seam on non-JBoss
              application servers. If you are going to be looking up the Seam EJB component through JSF (in
              a JSF view or as a JSF action listener) or a Seam JavaBean component, then you must declare
              the EJB reference in web.xml. Here is the EJB reference for the example component just shown:
              <ejb-local-ref>
              <ejb-ref-name>myapp/AuthenticatorBean/local</ejb-ref-name>
              <ejb-ref-type>Session</ejb-ref-type>
              <local>org.example.vehicles.action.Authenticator</local>
              </ejb-local-ref>
              This reference will cover most uses of the component in a Seam application. However, if you want
              to be able to inject a Seam EJB component into another Seam EJB component using @In, you
              need to define this EJB reference in another location. This time, it must be defined in ejb-jar.xml,
              and it's a bit tricker.



              So the answer depends on from what components you are trying to reference EJB components in non-JBoss app servers.  If you're referencing an EJB component from JSF or JavaBean, then you need the config in web.xml for that EJB.  If you're injecting an EJB component from another EJB component, then you need the config in ejb-jar.xml.  So you may have to configure the EJB in both descriptors potentially depending on the usage/referencing to that EJB component.  What a hassle!  (Remember J2EE 1.4?)


              And then it states that the rules for non-JBoss servers applies to JBoss AS 5 as well:


              Unlike with the web context, however, you cannot declare EJB references globally for all EJB
              components. Instead, you have to specify the JNDI resources for a given EJB component oneby-
              one (this applies to JBoss AS 5 in addition to non-JBoss application servers).



              How confusing!