[jboss-cvs] JBossAS SVN: r106312 - in projects/ejb3/trunk/core/src/main: java/org/jboss/ejb3/mdb and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Jun 29 12:46:05 EDT 2010


Author: jaikiran
Date: 2010-06-29 12:46:05 -0400 (Tue, 29 Jun 2010)
New Revision: 106312

Modified:
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessageContainerInvocation.java
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainerInvocation.java
   projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java
   projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml
Log:
EJBTHREE-2125 Allow invocation of timeout methods with non-public method access modifiers on EJBs

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java	2010-06-29 16:39:33 UTC (rev 106311)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/EJBContainer.java	2010-06-29 16:46:05 UTC (rev 106312)
@@ -33,6 +33,7 @@
 import java.lang.reflect.Proxy;
 import java.security.Principal;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -68,9 +69,12 @@
 import org.jboss.aop.MethodInfo;
 import org.jboss.aop.advice.AdviceStack;
 import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.advice.PerVmAdvice;
 import org.jboss.aop.annotation.AnnotationRepository;
+import org.jboss.aop.joinpoint.Joinpoint;
 import org.jboss.aop.microcontainer.annotations.DisableAOP;
 import org.jboss.aop.util.MethodHashing;
+import org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor;
 import org.jboss.beans.metadata.api.annotations.Inject;
 import org.jboss.ejb.AllowedOperationsAssociation;
 import org.jboss.ejb3.annotation.Clustered;
@@ -83,6 +87,7 @@
 import org.jboss.ejb3.injection.InjectionInvocation;
 import org.jboss.ejb3.interceptor.InterceptorInfoRepository;
 import org.jboss.ejb3.interceptor.InterceptorInjector;
+import org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor;
 import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor;
 import org.jboss.ejb3.interceptors.direct.DirectContainer;
 import org.jboss.ejb3.interceptors.direct.IndirectContainer;
@@ -1939,4 +1944,23 @@
    {
       throw new UnsupportedOperationException("NYI");
    }
+   
+   /**
+    * 
+    * @param joinPoint
+    * @param interceptorStackName
+    * @return
+    */
+   protected Interceptor[] getInterceptors(Joinpoint joinPoint, String interceptorStackName)
+   {
+      AdviceStack stack = this.getAdvisor().getManager().getAdviceStack(interceptorStackName);
+      if (stack == null)
+      {
+         log.debug("No AOP interceptor stack with name : " + interceptorStackName + " available for EJB container: " + this);
+         return new Interceptor[0];
+      }
+      List<Interceptor> interceptors = new ArrayList<Interceptor>();
+      interceptors.addAll(Arrays.asList(stack.createInterceptors(this.getAdvisor(), joinPoint)));
+      return interceptors.toArray(new Interceptor[]{});
+   }
 }

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessageContainerInvocation.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessageContainerInvocation.java	2010-06-29 16:39:33 UTC (rev 106311)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessageContainerInvocation.java	2010-06-29 16:46:05 UTC (rev 106312)
@@ -22,10 +22,13 @@
 package org.jboss.ejb3.mdb;
 
 import org.jboss.aop.MethodInfo;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.ejb3.BeanContext;
 import org.jboss.ejb3.EJBContainerInvocation;
 import org.jboss.ejb3.context.spi.InvocationContext;
 import org.jboss.ejb3.core.context.InvocationContextAdapter;
+import org.jboss.ejb3.session.SessionContainerInvocation;
 
 /**
  * @author <a href="cdewolf at redhat.com">Carlo de Wolf</a>
@@ -39,6 +42,25 @@
       super(info);
       this.invocationContext = new InvocationContextAdapter(this);
    }
+   
+   /**
+    * /**
+    * Creates a {@link MessageContainerInvocation}.
+    * <p>
+    *   This constructor is similar to {@link #MessageContainerInvocation(MethodInfo)} except that this
+    *   constructor overwrites the interceptors for this {@link Invocation} with the passed <code>interceptors</code>.
+    *   This effectively, ignores the interceptors available from {@link MethodInfo#getInterceptors()} 
+    * </p>
+    * 
+    * @param info The {@link MethodInfo}
+    * @param interceptors The interceptors which will be used by this {@link Invocation}. 
+    */
+   public MessageContainerInvocation(MethodInfo info, Interceptor[] interceptors)
+   {
+      this (info);
+      this.interceptors = interceptors;
+   }
+   
 
    public InvocationContext getInvocationContext()
    {

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java	2010-06-29 16:39:33 UTC (rev 106311)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java	2010-06-29 16:46:05 UTC (rev 106312)
@@ -39,6 +39,7 @@
 
 import org.jboss.aop.Domain;
 import org.jboss.aop.MethodInfo;
+import org.jboss.aop.advice.Interceptor;
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.ejb3.BeanContext;
 import org.jboss.ejb3.EJBContainerInvocation;
@@ -67,6 +68,9 @@
    private static final Logger log = Logger.getLogger(MessagingContainer.class);
    
    private Method timeout;
+   
+   private static final String MDB_TIMEOUT_METHOD_AOP_INTERCEPTOR_STACK_NAME = "MessageDrivenBeanTimeoutMethodStack";
+   
    protected ActivationSpec activationSpec = new ActivationSpec();
    protected JBossMessageEndpointFactory messageEndpointFactory;
    private MessagingDelegateWrapper mbean = new MessagingDelegateWrapper(this);
@@ -647,14 +651,39 @@
       Object[] args = {timer};
       if(tMethod.getParameterTypes().length == 0)
          args = null;
+
+      MethodInfo info = getMethodInfo(tMethod);
+      if (info == null)
+      {
+         throw new RuntimeException("Could not find timeout method info: " + tMethod.toString() + " for container " + this);
+      }
+      // get hold of the unadvised method, so that we can mark it accessible
+      // for the duration of this call (Remember, timeout methods can be with private, protected, package access modifier)
+      Method unadvisedMethod = info.getUnadvisedMethod();
+      // store the old value of method accesibility, so that it can be restored later 
+      boolean unadvisedMethodAccessibilityOldVal = unadvisedMethod.isAccessible();
+      // mark as accessible before invoking
+      unadvisedMethod.setAccessible(true);
       try
       {
-         localInvoke(tMethod, args);
+         // the timeout method (even if private, protected etc...) should pass through the AOP interceptor
+         // chain. Hence we have a specific AOP interceptor stack for timeout method. Get hold of those interceptors
+         Interceptor[] timeoutMethodAOPInterceptors = this.getInterceptors(info.getJoinpoint(),MDB_TIMEOUT_METHOD_AOP_INTERCEPTOR_STACK_NAME);
+         // now create an invocation for the method info and the timeout method interceptors         
+         EJBContainerInvocation nextInvocation = new MessageContainerInvocation(info, timeoutMethodAOPInterceptors);
+         nextInvocation.setAdvisor(getAdvisor());
+         nextInvocation.setArguments(args);
+         nextInvocation.invokeNext();
       }
       catch (Throwable throwable)
       {
          if (throwable instanceof Exception) throw (Exception) throwable;
          throw new RuntimeException(throwable);
       }
+      finally
+      {
+         // reset the timeout method accessibility
+         unadvisedMethod.setAccessible(unadvisedMethodAccessibilityOldVal);
+      }
    }
 }
\ No newline at end of file

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainerInvocation.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainerInvocation.java	2010-06-29 16:39:33 UTC (rev 106311)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/session/SessionContainerInvocation.java	2010-06-29 16:46:05 UTC (rev 106312)
@@ -22,6 +22,8 @@
 package org.jboss.ejb3.session;
 
 import org.jboss.aop.MethodInfo;
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.ejb3.BeanContext;
 import org.jboss.ejb3.EJBContainerInvocation;
 import org.jboss.ejb3.context.spi.SessionInvocationContext;
@@ -39,7 +41,26 @@
       super(info);
       this.invocationContext = new SessionInvocationContextAdapter(invokedBusinessInterface, this);
    }
+   
+   /**
+    * Creates a {@link SessionContainerInvocation}.
+    * <p>
+    *   This constructor is similar to {@link #SessionContainerInvocation(Class, MethodInfo)} except that this
+    *   constructor overwrites the interceptors for this {@link Invocation} with the passed <code>interceptors</code>.
+    *   This effectively, ignores the interceptors available from {@link MethodInfo#getInterceptors()} 
+    * </p>
+    * 
+    * @param invokedBusinessInterface The invoked business interface
+    * @param info The {@link MethodInfo}
+    * @param interceptors The interceptors which will be used by this {@link Invocation}. 
+    */
+   public SessionContainerInvocation(Class<?> invokedBusinessInterface, MethodInfo info, Interceptor[] interceptors)
+   {
+      this(invokedBusinessInterface, info);
+      this.interceptors = interceptors;
+   }
 
+
    public SessionInvocationContext getInvocationContext()
    {
       return invocationContext;

Modified: projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java
===================================================================
--- projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java	2010-06-29 16:39:33 UTC (rev 106311)
+++ projects/ejb3/trunk/core/src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java	2010-06-29 16:46:05 UTC (rev 106312)
@@ -41,6 +41,7 @@
 import org.jboss.aop.Advisor;
 import org.jboss.aop.Domain;
 import org.jboss.aop.MethodInfo;
+import org.jboss.aop.advice.Interceptor;
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.InvocationResponse;
 import org.jboss.aop.joinpoint.MethodInvocation;
@@ -102,6 +103,9 @@
    private static final Logger log = Logger.getLogger(StatelessContainer.class);
 
    private Method timeout;
+   
+   private static final String SLSB_TIMEOUT_METHOD_AOP_INTERCEPTOR_STACK_NAME = "StatelessBeanTimeoutMethodStack";
+
    private StatelessDelegateWrapper mbean = new StatelessDelegateWrapper(this);
 
    public StatelessContainer(ClassLoader cl, String beanClassName, String ejbName, Domain domain,
@@ -653,13 +657,28 @@
       if (tMethod.getParameterTypes().length == 0)
          args = null;
       ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+
       try
       {
          AllowedOperationsAssociation.pushInMethodFlag(AllowedOperationsFlags.IN_EJB_TIMEOUT);
+
+         // get the method info (AOP stuff)
+         MethodInfo info = super.getMethodInfo(tMethod);
+         // get hold of the unadvised method, so that we can mark it accessible
+         // for the duration of this call (Remember, timeout methods can be with private, protected, package access modifier)
+         Method unadvisedMethod = info.getUnadvisedMethod();
+         // store the old value of method accesibility, so that it can be restored later 
+         boolean unadvisedMethodAccessibilityOldVal = unadvisedMethod.isAccessible();
+         // mark as accessible before invoking
+         unadvisedMethod.setAccessible(true);
+
          try
          {
-            MethodInfo info = super.getMethodInfo(tMethod);
-            EJBContainerInvocation nextInvocation = new SessionContainerInvocation(null, info);
+            // the timeout method (even if private, protected etc...) should pass through the AOP interceptor
+            // chain. Hence we have a specific AOP interceptor stack for timeout method. Get hold of those interceptors
+            Interceptor[] timeoutMethodAOPInterceptors = this.getInterceptors(info.getJoinpoint(),SLSB_TIMEOUT_METHOD_AOP_INTERCEPTOR_STACK_NAME);
+            // now create an invocation for the method info and the timeout method interceptors
+            EJBContainerInvocation nextInvocation = new SessionContainerInvocation(null, info, timeoutMethodAOPInterceptors);
             nextInvocation.setAdvisor(getAdvisor());
             nextInvocation.setArguments(args);
             nextInvocation.invokeNext();
@@ -672,15 +691,20 @@
          }
          finally
          {
+            // reset the timeout method accessibility
+            unadvisedMethod.setAccessible(unadvisedMethodAccessibilityOldVal);
+
             AllowedOperationsAssociation.popInMethodFlag();
+
          }
       }
       finally
       {
          Thread.currentThread().setContextClassLoader(oldLoader);
       }
-   }   
+   }
    
+   
    static class WSCallbackImpl implements BeanContextLifecycleCallback
    {
       private ExtensibleWebServiceContext jaxwsContext;

Modified: projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml
===================================================================
--- projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml	2010-06-29 16:39:33 UTC (rev 106311)
+++ projects/ejb3/trunk/core/src/main/resources/ejb3-interceptors-aop.xml	2010-06-29 16:46:05 UTC (rev 106312)
@@ -146,6 +146,13 @@
          <advice name="setup" aspect="InvocationContextInterceptor"/>
          <interceptor-ref name="CurrentInvocationContextInterceptor"/>
       </stack>
+      
+      <stack name="TimeoutMethodStack">
+        <interceptor-ref name="org.jboss.ejb3.interceptor.EJB3TCCLInterceptor"/>
+        <interceptor-ref name="org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor"/>
+        <interceptor-ref name="CurrentInvocationContextInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.BlockContainerShutdownInterceptor"/>
+      </stack>
    </domain>
 
 
@@ -177,6 +184,30 @@
       <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.Pool)">
          @org.jboss.ejb3.annotation.Pool (value="ThreadlocalPool", maxSize=30, timeout=10000)
       </annotation>
+      
+            
+      <stack name="StatelessBeanTimeoutMethodStack">
+
+      	<!--  Include the common timeout method stack
+      		After JBAS-8130, just use this stack-ref and remove the 4 duplicate listed interceptor-refs
+      		below 
+      	<stack-ref name="TimeoutMethodStack"/> -->
+
+      	<interceptor-ref name="org.jboss.ejb3.interceptor.EJB3TCCLInterceptor"/>
+        <interceptor-ref name="org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor"/>
+        <interceptor-ref name="CurrentInvocationContextInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.BlockContainerShutdownInterceptor"/>
+
+      	<!--  The additional SLSB specific ones -->
+		<interceptor-ref name="org.jboss.ejb3.ENCPropagationInterceptor"/>
+        <interceptor-ref name="org.jboss.aspects.tx.TxPropagationInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.tx.CMTTxInterceptorFactory"/>
+        <interceptor-ref name="org.jboss.ejb3.stateless.StatelessInstanceInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.tx.BMTTxInterceptorFactory"/>
+        <interceptor-ref name="org.jboss.ejb3.AllowedOperationsInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor"/>
+      </stack>
+      
    </domain>
 
    <domain name="JACC Stateless Bean" extends="Intercepted Bean" inheritBindings="true">
@@ -375,6 +406,30 @@
       <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.Pool)">
          @org.jboss.ejb3.annotation.Pool (value="StrictMaxPool", maxSize=15, timeout=10000)
       </annotation>
+      
+      <stack name="MessageDrivenBeanTimeoutMethodStack">
+
+      	<!--  Include the common timeout method stack
+      		After JBAS-8130, just use this stack-ref and remove the 4 duplicate listed interceptor-refs
+      		below 
+      	<stack-ref name="TimeoutMethodStack"/>
+      	-->
+      	<interceptor-ref name="org.jboss.ejb3.interceptor.EJB3TCCLInterceptor"/>
+        <interceptor-ref name="org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor"/>
+        <interceptor-ref name="CurrentInvocationContextInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.BlockContainerShutdownInterceptor"/>
+
+		<!--  The additional MDB specific ones -->
+		<interceptor-ref name="org.jboss.ejb3.ENCPropagationInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.tx.CMTTxInterceptorFactory"/>
+        <interceptor-ref name="org.jboss.ejb3.stateless.StatelessInstanceInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.tx.BMTTxInterceptorFactory"/>
+        <interceptor-ref name="org.jboss.ejb3.AllowedOperationsInterceptor"/>
+        <interceptor-ref name="org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor"/>
+         
+      	         
+      </stack>
+      
    </domain>
 
    <domain name="Consumer Bean" extends="Intercepted Bean" inheritBindings="true">



More information about the jboss-cvs-commits mailing list