nested Interceptor-calls
ret May 17, 2010 5:11 AMHello there,
i noticed, that nested methodcalls not raise an interception if the methods ar called from an @Interceptor-annotated method (tested for same Interceptor).
an example:
@Stateless @Interceptors(LogInterceptor.class) public class ParameterServiceImpl extends BaseEntityServiceImpl<Parameter> implements ParameterService, ParameterServiceLocal { ... @Interceptors(ParameterReloader.class) // first i tried without this... public void create(String name, String value, Company company, boolean visible, boolean readonly) { Parameter p = new Parameter(name, value, company, visible, readonly); this.create(p); } @Override @Interceptors(ParameterReloader.class) public void create(Parameter entity) { super.create(entity); } ... }
the first method calls the create(Parameter)-method, but the 2nd methodcall does not raise Interception.
At first i tried it without annotating the first method and wondering that nothing happens (expected Action if the 2nd method get called).
So this is a bug or a feature to prevent infinite Interceptor-loops?
App-Logs:
2010-05-14 17:10:04,122 DEBUG [de.xxx.business.service.core.CompanyServiceImpl] create(Integer,String) in 10ms 2010-05-14 17:10:04,122 DEBUG [de.xxx.business.service.core.interceptor.ParameterReloader] ParameterReloader: executed method = create 2010-05-14 17:10:04,153 DEBUG [de.xxx.business.service.core.ParameterServiceImpl] findByName(String,Company) in 3ms 2010-05-14 17:10:04,153 DEBUG [de.xxx.business.service.core.ParameterHolderImpl] reload(String,Company) in 5ms
my Interceptor:
@Interceptor public class ParameterReloader { private Log LOG = LogFactory.getLog(this.getClass()); @Resource private EJBContext ejbContext; @AroundInvoke public Object intercept(InvocationContext context) throws Exception{ LOG.debug("ParameterReloader: executed method = " + context.getMethod().getName()); try { return context.proceed(); } finally { try { Object[] par = context.getParameters(); String mname = context.getMethod().getName(); // wenn Methodenname delete oder create oder update if ("delete".equals(mname) || "create".equals(mname) || "update".equals(mname)) { ParameterHolderLocal ph = (ParameterHolderLocal) ejbContext.lookup(ParameterHolderLocal.JNDI_BINDING); // wenn nur ein Argument übergeben (Parameter) if (par.length == 1 && par[0] instanceof Parameter) { Parameter p = (Parameter) par[0]; // wenn in delete-Methode if ("delete".equals(mname)) { ph.unload(p); // sonst update oder create } else { ph.reload(p); } // public void create(String name, String value, Company company, boolean visible, boolean readonly) // public void create(String name, String value, Company company) } else if ((par.length == 5 || par.length == 3 ) && par[0] instanceof String && par[2] instanceof Company) { ph.reload((String) par[0], (Company) par[2]); } } } catch (final Exception e) { // Pokemon Exception Handling - gotta catch 'em all! if (LOG.isWarnEnabled()) { LOG.warn("cannot refresh ParameterHolder: ", e); } } } } }