2 Replies Latest reply on Jul 2, 2008 5:58 AM by chawax

    Interceptors don't work

    chawax

      Hi,

      I use Embedded JBoss beta 3 in a Maven project and run unit tests with TestNG. It took a long time but now the embedded container starts well and the tests are successful. But when I configure interceptors in ejb-jar.xml, it looks like they are ignored.

      Interceptors are configured this way in ejb-jar.xml file :

      <assembly-descriptor>
       <interceptor-binding>
       <ejb-name>EmployeeBaseServiceBean</ejb-name>
       <interceptor-class>t4.core.employee.SecurityInterceptor</interceptor-class>
       </interceptor-binding>
       <interceptor-binding>
       <ejb-name>EmployeeInternalServiceBean</ejb-name>
       <interceptor-class>t4.core.employee.SecurityInterceptor</interceptor-class>
       </interceptor-binding>
      </assembly-descriptor>


      And I start Embedded JBoss this way :

      @BeforeSuite
      public void startup()
      {
       try {
       if (! Bootstrap.getInstance().isStarted()) {
       Bootstrap bootstrap = Bootstrap.getInstance();
       bootstrap.bootstrap();
       bootstrap.deployResourceBases("META-INF/ejb-jar.xml");
       }
       }
       catch (Exception ex)
       {
       logger.error(ex.getMessage(), ex);
       throw new RuntimeException(ex);
       }
      }


      I think ejb-jar.xml is OK because interceptors work when I deploy my EJBs on a JBoss application server. So I think there's something wrong in the way I start and deploy Embedded JBoss. Anyone has an idea ?

      Thanks in advance ;)

      Olivier

        • 1. Re: Interceptors don't work
          chawax

          I still work on this problem and still can't understand what happens. I set log level to DEBUG and it looks like Embedded JBoss finds my interceptor because I can see this in the logs:

          DEBUG [org.jboss.ejb3.EJBContainer] Initialising interceptors for EmployeeInternalServiceBean...
          DEBUG [org.jboss.ejb3.EJBContainer] Default interceptors: []
          DEBUG [org.jboss.ejb3.EJBContainer] Class interceptors: [InterceptorInfo{class=class t4.core.employee.SecurityInterceptor, aroundInvoke=execute}]
          DEBUG [org.jboss.ejb3.EJBContainer] All applicable interceptor classes: [InterceptorInfo{class=class t4.core.employee.SecurityInterceptor, aroundInvoke=execute}]
          DEBUG [org.jboss.injection.PersistenceUnitHandler] ***** adding PU dependency from located persistence unit: persistence.units:jar=classes.jar,unitName=t4Seam
          DEBUG [org.jboss.injection.PersistenceUnitHandler] ***** adding PU dependency from located persistence unit: persistence.units:jar=classes.jar,unitName=t4Seam
          DEBUG [org.jboss.injection.PersistenceUnitHandler] ***** adding PU dependency from located persistence unit: persistence.units:jar=classes.jar,unitName=t4Seam


          But when I call this EJB session bean, interceptor is not invoked.

          Could it come from the way I call my EJB session bean in tests ?

          My test class is as following :

          EmployeeInternalServiceLocal employeeService =
           (EmployeeInternalServiceLocal) EJB3Container.getInitialContext("admin", "admin")
           .lookup("EmployeeInternalServiceBean/local");
          


          And EJB3Container class :

          private static InitialContext securedInitialContext = null;
          
          public static InitialContext getInitialContext(String principal, String credential)
           throws
          {
           if (securedInitialContext == null)
           {
           Hashtable props = getInitialContextProperties(principal, credential);
           securedInitialContext = new InitialContext(props);
           }
           return securedInitialContext;
          }
          
          private static Hashtable getInitialContextProperties(String principal, String credential)
          {
           Hashtable<String, String> props = new Hashtable<String, String>();
           props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory");
           props.put(Context.SECURITY_PRINCIPAL, principal);
           props.put(Context.SECURITY_CREDENTIALS, credential);
           return props;
          }


          • 2. Re: Interceptors don't work
            chawax

            I found where my problem comes from and I think there is a bug in the way Embedded JBoss binds interceptors to EJB session beans methods. It looks like it binds interceptors to public methods, but public methods declared in super classes are ignored !

            In my case, EJB session beans classes are generated with a MDA framework called AndroMDA. For any EJB SB methods in my UML model, it creates two classes :
            - An abstract base class, with public methods implementing default behaviours (parameters validation, exception handling, ...) and calling an abstract method for business logic that can't be modeled.
            - An implementation class, which inherits the base class and contains implementation for its abstract methods, i.e. implementation of business logic. That is this class that is defined as SLSB in ejb-jar.xml. And it looks like Embedded JBoss looks for public methods to bind interceptors only in this class, and not in the inherited ones.

            Let me show you an example ...

            I have an EmployeeInternalServiceBase class with the following methods :

            public java.util.Collection loadAllEmployees()
             {
             try
             {
             return this.handleLoadAllEmployees();
             }
             catch (Throwable th)
             {
             throw new t4.core.employee.internal.EmployeeInternalServiceException(
             "Error performing 't4.core.employee.internal.EmployeeInternalService.loadAllEmployees()' --> " + th,
             th);
             }
             }
            
             protected abstract java.util.Collection handleLoadAllEmployees()
             throws java.lang.Exception;
            


            I have an EmployeeInternalServiceBean class that extends EmployeeInternalServiceBase and implements its abstract methods :


            protected java.util.Collection handleLoadAllEmployees()
             throws java.lang.Exception
             {
             return getEmployeeDao().loadAll();
             }
            


            Some extracts from my ejb-jar.xml :

            <session>
             <description>
             <![CDATA[
            
             ]]>
             </description>
             <ejb-name>EmployeeInternalServiceBean</ejb-name>
             <local>t4.core.employee.internal.EmployeeInternalServiceLocal</local>
             <ejb-class>t4.core.employee.internal.EmployeeInternalServiceBean</ejb-class>
             <session-type>Stateless</session-type>
             <transaction-type>Container</transaction-type>
             </session>
            


            <assembly-descriptor>
             <interceptor-binding>
             <ejb-name>EmployeeInternalServiceBean</ejb-name>
             <interceptor-class>fr.horoquartz.t4.core.employee.SecurityInterceptor</interceptor-class>
             </interceptor-binding>
             </assembly-descriptor>
            


            Interceptors are never bound for methods in this session bean.

            Now, I add this method to my EJB session bean :

            public java.util.Collection loadAllMyEmployees() {
             return this.loadAllEmployees();
            }


            This time, interceptors are bound and I can see this in the logs :

            DEBUG [org.jboss.ejb3.EJBContainer] Initialising interceptors for EmployeeInternalServiceBean...
            DEBUG [org.jboss.ejb3.EJBContainer] Default interceptors: []
            DEBUG [org.jboss.ejb3.EJBContainer] Class interceptors: [InterceptorInfo{class=class t4.core.employee.SecurityInterceptor, aroundInvoke=execute}]
            DEBUG [org.jboss.ejb3.EJBContainer] All applicable interceptor classes: [InterceptorInfo{class=class t4.core.employee.SecurityInterceptor, aroundInvoke=execute}]
            DEBUG [org.jboss.ejb3.interceptor.EJB3InterceptorsFactory] Bound interceptors for joinpoint: public java.util.Collection t4.core.employee.internal.EmployeeInternalServiceBean.loadAllMyEmployees() - [InterceptorInfo{class=class t4.core.employee.SecurityInterceptor, aroundInvoke=execute}]
            


            I think this test puts in evidence there's a bug about this in Embedded JBoss, doesn't it ?