-
1. Re: Interceptors don't work
chawax Jul 1, 2008 9:30 AM (in response to 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 Jul 2, 2008 5:58 AM (in response to 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 ?