|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Possible OPENEJB Bug with Interceptors?Apologies in advance if this has been already reported or I have it wrong. I've searched and it seems that no one else has encountered my specific problem....
The issue I'm having in a nutshell is that my interceptor is not being called for public session bean methods that are called from within other methods in the same class. This is a problem for me because I'm trying to do some exception handling in my generic interceptor, and it is getting bypassed when a session bean method is called from another method. Here's an example: /////// interceptor public class TestInterceptor { @AroundInvoke public Object interceptor(InvocationContext invocation) throws Exception { System.out.println("Interceptor invoked!"); return invocation.proceed(); } } ///////// session bean interface @Local public interface mySessionBeanLocal { public void method1(); public void method2(); } ///////// session bean impl @Stateful @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) @Interceptors(TestInterceptor .class) public class mySessionBean implements mySessionBeanLocal { @Override public void method1() { System.out.println("Method 1 invoked!"); method2(); } @Override public void method2() { System.out.println("Method 2 invoked!"); } } I have a junit test case that is annotated with @LocalClient and has an injected copy of mySessoinBeanLocal using @EJB. When my unit test calls method1(), it appears that the interceptor is only triggered when method1() is called but not when method2() is invoked by method1(). If I deploy the same code on JBoss, the interceptor is tripped twice as I would expect it to be. (I'm using Openejb 3.1.1) Any thoughts/advice/workarounds would be greatly appreciated! Is this a bug in openejb or a bug in JBoss? (or a bug in my reasoning... ) |
|
|
Re: Possible OPENEJB Bug with Interceptors?On Oct 22, 2009, at 1:05 PM, Marrrck wrote: > The issue I'm having in a nutshell is that my interceptor is not being > called for public session bean methods that are called from within > other > methods in the same class. > ///////// session bean impl > @Stateful > @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) > @Interceptors(TestInterceptor .class) > public class mySessionBean implements mySessionBeanLocal { > > @Override > public void method1() { > System.out.println("Method 1 invoked!"); > method2(); > } > > @Override > public void method2() { > System.out.println("Method 2 invoked!"); > } > } Per EJB spec if you wanted container managed anything you have to go through the business interface. This is the motivation for these methods on javax.ejb.SessionContext: javax.ejb.EJBLocalObject getEJBLocalObject(); javax.ejb.EJBObject getEJBObject(); java.lang.Object getBusinessObject(java.lang.Class aClass); You can do what you want portably like so: @Override public void method1() { System.out.println("Method 1 invoked!"); sessionContext.getBusinessObject(mySessionBeanLocal.class).method2(); } Clearly JBoss is using byte code enhancement to add container managed features directly to your bean class. This is certainly a neat idea -- kicked it around myself a few times -- but not a feature of EJB. I don't know if I'd go as far to say that it's illegal or a bug, but it is definitely a very container specific feature (really more like a very container specific architecture). -David |
|
|
Re: Possible OPENEJB Bug with Interceptors?Ah, thanks for the clarification! Unfortunately this solution won't work for me because the session bean is stateful. When I modify the code like this:
///////// session bean impl @Stateful @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) @Interceptors(TestInterceptor .class) public class mySessionBean implements mySessionBeanLocal { @Resource private SessionConext context; @Override public void method1() { System.out.println("Method 1 invoked!"); context.getBusinessObject(mySessionBeanLocal.class).method2(); } @Override public void method2() { System.out.println("Method 2 invoked!"); } } I get a "Concurrent calls not allowed" exception: javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: javax.ejb.EJBException: Concurrent calls not allowed at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:358) at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:286) at $Proxy117.method1(Unknown Source) //.... Caused by: javax.ejb.EJBException: Concurrent calls not allowed at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:358) at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:286) at $Proxy117.Method2(Unknown Source) //... Caused by: java.rmi.RemoteException: Concurrent calls not allowed at org.apache.openejb.core.stateful.StatefulContainer.obtainInstance(StatefulContainer.java:635) at org.apache.openejb.core.stateful.StatefulContainer.businessMethod(StatefulContainer.java:484) at org.apache.openejb.core.stateful.StatefulContainer.invoke(StatefulContainer.java:274) at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:217) at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:77) at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:281) ... 56 more Not sure what the right thing to do is here. I guess the easiest thing would be to move method2 into a different stateful session bean and inject that into the first session bean? "A session bean method should never invoke another public method defined by that session bean's business interface" seems like kind of an arbitrary rule though. Or I guess I could just not rely on interceptors....
|
|
|
Re: Possible OPENEJB Bug with Interceptors?On Oct 23, 2009, at 7:48 AM, Marrrck wrote: > I get a "Concurrent calls not allowed" exception: This is a bug. Filed it here: https://issues.apache.org/jira/browse/OPENEJB-1099 > Not sure what the right thing to do is here. I guess the easiest > thing would > be to move method2 into a different stateful session bean and inject > that > into the first session bean? That would definitely work. -David |
| Free embeddable forum powered by Nabble | Forum Help |