You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by Marrrck <mm...@gmail.com> on 2009/10/22 22:05:40 UTC

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... )
-- 
View this message in context: http://www.nabble.com/Possible-OPENEJB-Bug-with-Interceptors--tp26016326p26016326.html
Sent from the OpenEJB User mailing list archive at Nabble.com.


Re: Possible OPENEJB Bug with Interceptors?

Posted by David Blevins <da...@visi.com>.
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


Re: Possible OPENEJB Bug with Interceptors?

Posted by Marrrck <mm...@gmail.com>.
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....


David Blevins wrote:
> 
> 
> 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
> 
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-OPENEJB-Bug-with-Interceptors--tp26016326p26027751.html
Sent from the OpenEJB User mailing list archive at Nabble.com.


Re: Possible OPENEJB Bug with Interceptors?

Posted by David Blevins <da...@visi.com>.
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