Checked in a fix. TCK seems to like it so far. -David
On Jun 6, 2011, at 4:53 AM, Shawn Jiang wrote: > This brought some ejb tx regressions on geronimo tck. I can't dig into it > because of my poor apache svn connection for now. > > ---------- Forwarded message ---------- > From: <[email protected]> > Date: Sat, Jun 4, 2011 at 9:45 AM > Subject: svn commit: r1131304 - in /openejb/trunk/openejb3/container: > openejb-core/src/main/java/org/apache/openejb/ > openejb-core/src/main/java/org/apache/openejb/assembler/classic/ > openejb-core/src/main/java/org/apache/openejb/core/managed/ > openejb-core/src/ma... > To: [email protected] > > > Author: dblevins > Date: Sat Jun 4 01:45:46 2011 > New Revision: 1131304 > > URL: http://svn.apache.org/viewvc?rev=1131304&view=rev > Log: > Fixes OPENEJB-1567: Overriding of per-interface transaction attributes only > supported for different method signatures > > Added: > > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java > Modified: > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java > > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java > > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java > > openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java > Sat Jun 4 01:45:46 2011 > @@ -41,6 +41,7 @@ import javax.ejb.Timer; > import javax.naming.Context; > import javax.persistence.EntityManagerFactory; > > +import com.sun.istack.internal.Nullable; > import org.apache.openejb.cdi.OWBInjector; > import org.apache.openejb.core.ExceptionType; > import org.apache.openejb.core.InstanceContext; > @@ -58,8 +59,6 @@ import org.apache.openejb.core.transacti > import org.apache.openejb.core.transaction.TransactionType; > import org.apache.openejb.util.Duration; > import org.apache.openejb.util.Index; > -import org.apache.openejb.util.LogCategory; > -import org.apache.openejb.util.Logger; > import org.apache.webbeans.config.WebBeansContext; > import org.apache.xbean.recipe.ConstructionException; > > @@ -126,6 +125,7 @@ public class BeanContext extends Deploym > private final Map<Method, TransactionType> methodTransactionType = new > HashMap<Method, TransactionType>(); > private final Map<Method, Method> methodMap = new HashMap<Method, > Method>(); > private final Map<Method, MethodContext> methodContextMap = new > HashMap<Method, MethodContext>(); > + private final Map<String, ViewContext> viewContextMap = new > HashMap<String, ViewContext>(); > > private Index<EntityManagerFactory,Map> extendedEntityManagerFactories; > > @@ -412,36 +412,57 @@ public class BeanContext extends Deploym > } > > public TransactionType getTransactionType(Method method) { > - // Check the cache > - TransactionType type = methodTransactionType.get(method); > - if (type != null) { > - return type; > - } > + return getTransactionType(method, null); > + } > + > + public TransactionType getTransactionType(Method method, InterfaceType > interfaceType) { > + > + MethodContext methodContext = null; > > - // Bean managed EJBs always get the BeanManaged policy > - if (isBeanManagedTransaction) { > - return TransactionType.BeanManaged; > + if (interfaceType != null) { > + methodContext = getViewMethodContext(method, > interfaceType.getSpecName()); > } > > - // Check the matching bean method for the supplied method > - Method beanMethod = getMatchingBeanMethod(method); > - if (beanMethod != null){ > - type = methodTransactionType.get(beanMethod); > - if (type != null) { > - return type; > - } > + if (methodContext == null) methodContext = > methodContextMap.get(method); > + > + if (methodContext == null) { > + final Method beanMethod = getMatchingBeanMethod(method); > + methodContext = getMethodContext(beanMethod); > } > > - // All transaction attributes should have been set during > deployment, so log a message > - Logger log = Logger.getInstance(LogCategory.OPENEJB, > "org.apache.openejb.util.resources"); > - log.debug("The following method doesn't have a transaction policy > assigned: " + method); > - > - // default transaction policy is required > - type = getTransactionType(); > - > - // cache this default to avoid extra log messages > - methodTransactionType.put(method, type); > - return type; > + return methodContext.getTransactionType(); > + > +// > +// // Check the cache > +// TransactionType type = methodTransactionType.get(method); > +// if (type != null) { > +// return type; > +// } > +// > +// // Bean managed EJBs always get the BeanManaged policy > +// if (isBeanManagedTransaction) { > +// return TransactionType.BeanManaged; > +// } > +// > +// // Check the matching bean method for the supplied method > +// Method beanMethod = getMatchingBeanMethod(method); > +// if (beanMethod != null){ > +// type = methodTransactionType.get(beanMethod); > +// if (type != null) { > +// return type; > +// } > +// } > +// > +// // All transaction attributes should have been set during > deployment, so log a message > +// Logger log = Logger.getInstance(LogCategory.OPENEJB, > "org.apache.openejb.util.resources"); > +// log.debug("The following method doesn't have a transaction policy > assigned: " + method); > +// > +// // default transaction policy is required > +// type = getTransactionType(); > +// > +// // cache this default to avoid extra log messages > +// methodTransactionType.put(method, type); > +// return type; > } > > public TransactionType getTransactionType() { > @@ -650,24 +671,41 @@ public class BeanContext extends Deploym > * TODO: Move to MethodContext > */ > public void setMethodTransactionAttribute(Method method, TransactionType > transactionType) throws OpenEJBException { > + setMethodTransactionAttribute(method, transactionType, null); > + } > > - // Only the NOT_SUPPORTED and REQUIRED transaction attributes may > be used for message-driven > - // bean message listener methods. The use of the other transaction > attributes is not meaningful > - // for message-driven bean message listener methods because there > is no pre-existing client transaction > - // context(REQUIRES_NEW, SUPPORTS) and no client to handle > exceptions (MANDATORY, NEVER). > - if (componentType.isMessageDriven() && !isBeanManagedTransaction) { > - if (transactionType != TransactionType.NotSupported && > transactionType != TransactionType.Required) { > - > - if ((method.equals(this.ejbTimeout) || > methodContextMap.get(method).isAsynchronous()) && transactionType == > TransactionType.RequiresNew) { > - // do nothing. This is allowed as the timer callback > method for a message driven bean > - // can also have a transaction policy of RequiresNew > Sec 5.4.12 of Ejb 3.0 Core Spec > - } else { > - throw new OpenEJBException("The transaction attribute " > + transactionType + " is not supported for the method " > - + method.getName() + " of > the Message Driven Bean " + beanClass.getName()); > - } > - } > + /** > + * TODO: Move to MethodContext > + */ > + public void setMethodTransactionAttribute(Method method, > TransactionType transactionType, String view) throws OpenEJBException { > + > +// method = getMatchingBeanMethod(method); > + > + if (view == null) { > + getMethodContext(method).setTransactionType(transactionType); > + } else { > + initViewMethodContext(method, > view).setTransactionType(transactionType); > } > - methodTransactionType.put(method, transactionType); > + > + return; > + > +// // Only the NOT_SUPPORTED and REQUIRED transaction attributes may > be used for message-driven > +// // bean message listener methods. The use of the other > transaction attributes is not meaningful > +// // for message-driven bean message listener methods because there > is no pre-existing client transaction > +// // context(REQUIRES_NEW, SUPPORTS) and no client to handle > exceptions (MANDATORY, NEVER). > +// if (componentType.isMessageDriven() && !isBeanManagedTransaction) > { > +// if (transactionType != TransactionType.NotSupported && > transactionType != TransactionType.Required) { > +// > +// if ((method.equals(this.ejbTimeout) || > methodContextMap.get(method).isAsynchronous()) && transactionType == > TransactionType.RequiresNew) { > +// // do nothing. This is allowed as the timer callback > method for a message driven bean > +// // can also have a transaction policy of RequiresNew > Sec 5.4.12 of Ejb 3.0 Core Spec > +// } else { > +// throw new OpenEJBException("The transaction attribute > " + transactionType + " is not supported for the method " > +// + method.getName() + " of > the Message Driven Bean " + beanClass.getName()); > +// } > +// } > +// } > +// methodTransactionType.put(method, transactionType); > } > > public List<Method> getRemoveMethods() { > @@ -1231,4 +1269,38 @@ public class BeanContext extends Deploym > } > return buffer.toString(); > } > + > + private MethodContext getViewMethodContext(Method method, String view) > { > + ViewContext viewContext = this.viewContextMap.get(view); > + return (viewContext == null) ? null : > viewContext.getMethodContext(method); > + } > + > + private MethodContext initViewMethodContext(Method method, String view) > { > + ViewContext viewContext = this.viewContextMap.get(view); > + if (viewContext == null) { > + viewContext = new ViewContext(); > + viewContextMap.put(view, viewContext); > + } > + > + return viewContext.initMethodContext(method); > + } > + > + public class ViewContext { > + > + private final Map<Method, MethodContext> methodContextMap = new > HashMap<Method, MethodContext>(); > + > + public MethodContext getMethodContext(Method method) { > + return methodContextMap.get(method); > + } > + > + public MethodContext initMethodContext(Method method) { > + MethodContext methodContext = methodContextMap.get(method); > + if (methodContext != null) return methodContext; > + > + methodContext = new MethodContext(BeanContext.this, method); > + methodContextMap.put(method, methodContext); > + > + return methodContext; > + } > + } > } > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodInfoUtil.java > Sat Jun 4 01:45:46 2011 > @@ -309,6 +309,105 @@ public class MethodInfoUtil { > return attributes; > } > > + public static Map<ViewMethod, MethodAttributeInfo> > resolveViewAttributes(List<? extends MethodAttributeInfo> infos, BeanContext > beanContext) { > + Map<ViewMethod, MethodAttributeInfo> attributes = new > LinkedHashMap<ViewMethod, MethodAttributeInfo>(); > + > + Method[] wildCardView = getWildCardView(beanContext).toArray(new > Method[]{}); > + > + for (MethodAttributeInfo attributeInfo : infos) { > + for (MethodInfo methodInfo : attributeInfo.methods) { > + > + if (methodInfo.ejbName == null || > methodInfo.ejbName.equals("*") || > methodInfo.ejbName.equals(beanContext.getEjbName())) { > + > + List<Method> methods = new ArrayList<Method>(); > + > + if (methodInfo.methodIntf == null) { > + methods.addAll(matchingMethods(methodInfo, > wildCardView)); > + } else if (methodInfo.methodIntf.equals("Home")) { > + methods.addAll(matchingMethods(methodInfo, > beanContext.getHomeInterface())); > + } else if (methodInfo.methodIntf.equals("Remote")) { > + if (beanContext.getRemoteInterface() != null) { > + methods.addAll(matchingMethods(methodInfo, > beanContext.getRemoteInterface())); > + } > + for (Class intf : > beanContext.getBusinessRemoteInterfaces()) { > + methods.addAll(matchingMethods(methodInfo, > intf)); > + } > + } else if (methodInfo.methodIntf.equals("LocalHome")) { > + methods.addAll(matchingMethods(methodInfo, > beanContext.getLocalHomeInterface())); > + } else if (methodInfo.methodIntf.equals("Local")) { > + if (beanContext.getLocalInterface() != null) { > + methods.addAll(matchingMethods(methodInfo, > beanContext.getLocalInterface())); > + } > + for (Class intf : > beanContext.getBusinessRemoteInterfaces()) { > + methods.addAll(matchingMethods(methodInfo, > intf)); > + } > + } else if > (methodInfo.methodIntf.equals("ServiceEndpoint")) { > + methods.addAll(matchingMethods(methodInfo, > beanContext.getServiceEndpointInterface())); > + } > + > + for (Method method : methods) { > + if (containerMethod(method)) { > + continue; > + } > + > + final ViewMethod viewMethod = new > ViewMethod(methodInfo.methodIntf, method); > + attributes.put(viewMethod, attributeInfo); > +// List<MethodAttributeInfo> methodAttributeInfos = > attributes.get(method); > +// if (methodAttributeInfos == null) { > +// methodAttributeInfos = new > ArrayList<MethodAttributeInfo>(); > +// attributes.put(method, methodAttributeInfos); > +// } > +// methodAttributeInfos.add(attributeInfo); > + } > + } > + } > + } > + return attributes; > + } > + > + public static class ViewMethod { > + private final String view; > + private final Method method; > + > + public ViewMethod(String view, Method method) { > + this.view = view; > + this.method = method; > + } > + > + public String getView() { > + return view; > + } > + > + public Method getMethod() { > + return method; > + } > + > + @Override > + public boolean equals(Object o) { > + if (this == o) return true; > + if (o == null || getClass() != o.getClass()) return false; > + > + ViewMethod that = (ViewMethod) o; > + > + if (!method.equals(that.method)) return false; > + if (view != null ? !view.equals(that.view) : that.view != null) > return false; > + > + return true; > + } > + > + @Override > + public int hashCode() { > + int result = view != null ? view.hashCode() : 0; > + result = 31 * result + method.hashCode(); > + return result; > + } > + > + @Override > + public String toString() { > + return String.format("%s : %s(%s)", view, method.getName(), > Join.join(", ", Classes.getSimpleNames(method.getParameterTypes()))); > + } > + } > + > private static boolean containerMethod(Method method) { > return (method.getDeclaringClass() == EJBObject.class || > method.getDeclaringClass() == EJBHome.class || > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/MethodTransactionBuilder.java > Sat Jun 4 01:45:46 2011 > @@ -17,6 +17,7 @@ > package org.apache.openejb.assembler.classic; > > import static > org.apache.openejb.assembler.classic.MethodInfoUtil.resolveAttributes; > +import static > org.apache.openejb.assembler.classic.MethodInfoUtil.resolveViewAttributes; > > import org.apache.openejb.BeanContext; > import org.apache.openejb.core.transaction.TransactionType; > @@ -50,25 +51,35 @@ public class MethodTransactionBuilder { > > methodTransactionInfos = normalize(methodTransactionInfos); > > - Map<Method, MethodAttributeInfo> attributes = > resolveAttributes(methodTransactionInfos, beanContext); > + final Map<MethodInfoUtil.ViewMethod, MethodAttributeInfo> > attributes = resolveViewAttributes(methodTransactionInfos, beanContext); > > Logger log = > Logger.getInstance(LogCategory.OPENEJB_STARTUP.createChild("attributes"), > MethodTransactionBuilder.class); > - if (log.isDebugEnabled()) { > - for (Map.Entry<Method, MethodAttributeInfo> entry : > attributes.entrySet()) { > - Method method = entry.getKey(); > - MethodTransactionInfo value = (MethodTransactionInfo) > entry.getValue(); > - log.debug("Transaction Attribute: " + method + " -- " + > MethodInfoUtil.toString(value)); > - } > - } > + final boolean debug = log.isDebugEnabled(); > + > + for (Map.Entry<MethodInfoUtil.ViewMethod, MethodAttributeInfo> > entry : attributes.entrySet()) { > + final MethodInfoUtil.ViewMethod viewMethod = entry.getKey(); > + final Method method = viewMethod.getMethod(); > + final String view = viewMethod.getView(); > + > + MethodTransactionInfo transactionInfo = (MethodTransactionInfo) > entry.getValue(); > > - for (Map.Entry<Method, MethodAttributeInfo> entry : > attributes.entrySet()) { > - MethodTransactionInfo value = (MethodTransactionInfo) > entry.getValue(); > + if (debug) log.debug("Transaction Attribute: " + method + " -- > " + MethodInfoUtil.toString(transactionInfo)); > > -// logger.info(entry.getKey().toString() +" "+ > value.transAttribute); > - beanContext.setMethodTransactionAttribute(entry.getKey(), > TransactionType.get(value.transAttribute)); > + beanContext.setMethodTransactionAttribute(method, > TransactionType.get(transactionInfo.transAttribute), view); > } > } > > + private static String getMethodInterface(MethodTransactionInfo value) { > + // We can only do this because we have previously processed all the > + // MethodTransactionInfo objects so there is one per method > + // It makes code like this easier to handle > + for (MethodInfo methodInfo : value.methods) { > + return methodInfo.methodIntf; > + } > + > + return null; > + } > + > /** > * This method splits the MethodTransactionInfo objects so that there is > * exactly one MethodInfo per MethodTransactionInfo. A single > MethodTransactionInfo > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java > Sat Jun 4 01:45:46 2011 > @@ -358,7 +358,7 @@ public class ManagedContainer implements > createContext.setCurrentAllowedStates(null); > > // Start transaction > - TransactionPolicy txPolicy = > createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod), > createContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod, > interfaceType), createContext); > > Instance instance = null; > try { > @@ -448,7 +448,7 @@ public class ManagedContainer implements > } > > // Start transaction > - TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod), > callContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, > interfaceType), callContext); > > Object returnValue = null; > boolean retain = false; > @@ -550,7 +550,7 @@ public class ManagedContainer implements > checkAuthorization(callMethod, interfaceType); > > // Start transaction > - TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod), > callContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, > interfaceType), callContext); > > Object returnValue = null; > Instance instance = null; > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java > Sat Jun 4 01:45:46 2011 > @@ -214,7 +214,7 @@ public class SingletonContainer implemen > > Object returnValue; > try { > - TransactionPolicy txPolicy = > createTransactionPolicy(beanContext.getTransactionType(callMethod), > callContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(beanContext.getTransactionType(callMethod, > callType), callContext); > > returnValue = null; > try { > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java > Sat Jun 4 01:45:46 2011 > @@ -33,7 +33,6 @@ import javax.ejb.EJBContext; > import javax.ejb.EJBException; > import javax.ejb.EJBHome; > import javax.ejb.EJBLocalHome; > -import javax.ejb.NoSuchEJBException; > import javax.ejb.RemoveException; > import javax.ejb.SessionBean; > import javax.ejb.SessionContext; > @@ -369,7 +368,7 @@ public class StatefulContainer implement > createContext.setCurrentAllowedStates(null); > > // Start transaction > - TransactionPolicy txPolicy = > createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod), > createContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod, > interfaceType), createContext); > > Instance instance = null; > try { > @@ -459,7 +458,7 @@ public class StatefulContainer implement > } > > // Start transaction > - TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod), > callContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, > interfaceType), callContext); > > Object returnValue = null; > boolean retain = false; > @@ -561,7 +560,7 @@ public class StatefulContainer implement > checkAuthorization(callMethod, interfaceType); > > // Start transaction > - TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod), > callContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, > interfaceType), callContext); > > Object returnValue = null; > Instance instance = null; > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java > Sat Jun 4 01:45:46 2011 > @@ -212,7 +212,7 @@ public class StatelessContainer implemen > > BeanContext beanContext = callContext.getBeanContext(); > > - TransactionPolicy txPolicy = > createTransactionPolicy(beanContext.getTransactionType(callMethod), > callContext); > + TransactionPolicy txPolicy = > createTransactionPolicy(beanContext.getTransactionType(callMethod, type), > callContext); > > Object returnValue = null; > try { > > Modified: > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/TransactionAttributesTest.java > Sat Jun 4 01:45:46 2011 > @@ -20,7 +20,9 @@ import static org.apache.openejb.assembl > import junit.framework.TestCase; > import org.apache.openejb.BeanContext; > import org.apache.openejb.config.ConfigurationFactory; > +import org.apache.openejb.core.ThreadContext; > import org.apache.openejb.jee.EjbJar; > +import org.apache.openejb.jee.InterceptorBinding; > import org.apache.openejb.jee.StatelessBean; > import org.apache.openejb.jee.ContainerTransaction; > import org.apache.openejb.jee.TransAttribute; > @@ -29,10 +31,18 @@ import static org.apache.openejb.assembl > import org.apache.openejb.spi.ContainerSystem; > import org.apache.openejb.loader.SystemInstance; > > +import javax.ejb.EJBTransactionRequiredException; > import javax.ejb.Local; > +import javax.ejb.LocalBean; > import javax.ejb.Remote; > import javax.ejb.TransactionAttribute; > +import javax.interceptor.AroundInvoke; > +import javax.interceptor.InvocationContext; > +import javax.transaction.TransactionRequiredException; > + > import static javax.ejb.TransactionAttributeType.*; > + > +import java.lang.reflect.InvocationTargetException; > import java.lang.reflect.Method; > import java.util.Map; > import java.util.List; > @@ -42,6 +52,7 @@ import java.util.List; > */ > public class TransactionAttributesTest extends TestCase { > private Map<Method, MethodAttributeInfo> attributes; > + private Object bean; > > public void test() throws Exception { > Assembler assembler = new Assembler(); > @@ -64,6 +75,8 @@ public class TransactionAttributesTest e > declared.add(new ContainerTransaction(TransAttribute.NEVER, > Red.class.getName(), "Scarlet", "red")); > declared.add(new ContainerTransaction(TransAttribute.REQUIRED, > "Scarlet", Scarlet.class.getMethod("scarlet"))); > > + ejbJar.getAssemblyDescriptor().addInterceptorBinding(new > InterceptorBinding("*", AttributeInterceptor.class.getName())); > + > EjbJarInfo ejbJarInfo = config.configureApplication(ejbJar); > assembler.createApplication(ejbJarInfo); > > @@ -119,11 +132,29 @@ public class TransactionAttributesTest e > BeanContext beanContext = system.getBeanContext(deploymentId); > List<MethodTransactionInfo> infos = > normalize(ejbJarInfo.methodTransactions); > attributes = resolveAttributes(infos, beanContext); > + bean = > system.getBeanContext(deploymentId).getBusinessLocalBeanHome().create(); > } > > - private void assertAttribute(String attribute, Method method) { > + private void assertAttribute(String attribute, Method method) throws > Exception { > MethodTransactionInfo info = (MethodTransactionInfo) > attributes.get(method); > assertEquals(method.toString(), attribute, info.transAttribute); > + > + try { > + final Object[] args = new > Object[method.getParameterTypes().length]; > + final Object result = method.invoke(bean, args); > + assertEquals(attribute, result); > + } catch (InvocationTargetException e) { > + assertEquals(attribute, "Mandatory"); > + assertTrue(e.getTargetException() instanceof > EJBTransactionRequiredException); > + } > + } > + > + public static class AttributeInterceptor { > + > + @AroundInvoke > + public Object invoke(InvocationContext context) throws Exception { > + return > ThreadContext.getThreadContext().getTransactionPolicy().getClass().getSimpleName().replace("Tx", > ""); > + } > } > > @Local > @@ -134,32 +165,33 @@ public class TransactionAttributesTest e > public static interface ColorRemote { > } > > + @LocalBean > @TransactionAttribute(MANDATORY) > public static class Color implements ColorLocal, ColorRemote { > > > @TransactionAttribute(NEVER) > - public void color(){} > + public String color(){return null;} > > > @TransactionAttribute(REQUIRES_NEW) > - public void color(Object o){} > + public String color(Object o){return null;} > > - public void color(String s){} > - public void color(Boolean b){} > - public void color(Integer i){} > + public String color(String s){return null;} > + public String color(Boolean b){return null;} > + public String color(Integer i){return null;} > } > > > public static class Red extends Color { > > - public void color(Object o){super.color(o);} > + public String color(Object o){return super.color(o);} > > @TransactionAttribute(REQUIRES_NEW) > - public void red(){} > + public String red(){return null;} > > - public void red(Object o){} > - public void red(String s){} > + public String red(Object o){return null;} > + public String red(String s){return null;} > > } > > @@ -167,22 +199,22 @@ public class TransactionAttributesTest e > public static class Crimson extends Red { > > > - public void color(){} > - public void color(String s){} > + public String color(){return null;} > + public String color(String s){return null;} > > @TransactionAttribute(REQUIRES_NEW) > - public void crimson(){} > + public String crimson(){return null;} > > - public void crimson(String s){} > + public String crimson(String s){return null;} > } > > @TransactionAttribute(NOT_SUPPORTED) > public static class Scarlet extends Red { > > @TransactionAttribute(REQUIRES_NEW) > - public void scarlet(){} > + public String scarlet(){return null;} > > - public void scarlet(String s){} > + public String scarlet(String s){return null;} > } > > } > > Added: > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java?rev=1131304&view=auto > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java > (added) > +++ > openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateless/InterfaceTransactionTest.java > Sat Jun 4 01:45:46 2011 > @@ -0,0 +1,97 @@ > +/** > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file distributed with > + * this work for additional information regarding copyright ownership. > + * The ASF licenses this file to You under the Apache License, Version 2.0 > + * (the "License"); you may not use this file except in compliance with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > +package org.apache.openejb.core.stateless; > + > +import junit.framework.TestCase; > +import org.apache.openejb.OpenEJB; > +import org.apache.openejb.jee.ContainerTransaction; > +import org.apache.openejb.jee.EjbJar; > +import org.apache.openejb.jee.Method; > +import org.apache.openejb.jee.MethodIntf; > +import org.apache.openejb.jee.StatelessBean; > +import org.apache.openejb.jee.TransAttribute; > +import org.apache.openejb.junit.ApplicationComposer; > +import org.apache.openejb.junit.Module; > +import org.junit.Test; > +import org.junit.runner.RunWith; > + > +import javax.ejb.EJB; > +import javax.ejb.EJBException; > +import javax.ejb.Local; > +import javax.ejb.Remote; > +import javax.ejb.Stateless; > +import javax.transaction.Status; > +import javax.transaction.SystemException; > +import java.util.List; > + > +/** > + * @version $Rev$ $Date$ > + */ > +@RunWith(ApplicationComposer.class) > +public class InterfaceTransactionTest extends TestCase { > + > + @EJB > + private OrangeRemote remote; > + > + @EJB > + private OrangeLocal local; > + > + @Module > + public EjbJar module() throws Exception { > + final EjbJar ejbJar = new EjbJar(); > + ejbJar.addEnterpriseBean(new StatelessBean(OrangeBean.class)); > + > + final Method remoteMethod = new Method("OrangeBean", > "isInTransaction").withInterface(MethodIntf.REMOTE); > + final Method localMethod = new Method("OrangeBean", > "isInTransaction").withInterface(MethodIntf.LOCAL); > + > + final List<ContainerTransaction> transactions = > ejbJar.getAssemblyDescriptor().getContainerTransaction(); > + > + transactions.add(new ContainerTransaction(TransAttribute.REQUIRED, > remoteMethod)); > + transactions.add(new ContainerTransaction(TransAttribute.SUPPORTS, > localMethod)); > + > + return ejbJar; > + } > + > + @Test > + public void test() { > + > + assertTrue(remote.isInTransaction()); > + assertFalse(local.isInTransaction()); > + } > + > + @Local > + public interface OrangeLocal { > + public boolean isInTransaction(); > + } > + > + @Remote > + public static interface OrangeRemote extends OrangeLocal { > + } > + > + @Stateless > + public static class OrangeBean implements OrangeLocal, OrangeRemote { > + > + @Override > + public boolean isInTransaction() { > + try { > + return Status.STATUS_ACTIVE == > OpenEJB.getTransactionManager().getStatus(); > + } catch (SystemException e) { > + throw new EJBException(e); > + } > + } > + } > +} > > Modified: > openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java > URL: > http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java?rev=1131304&r1=1131303&r2=1131304&view=diff > ============================================================================== > --- > openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java > (original) > +++ > openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java > Sat Jun 4 01:45:46 2011 > @@ -180,6 +180,11 @@ public class Method { > this.methodIntf = value; > } > > + public Method withInterface(MethodIntf methodIntf) { > + setMethodIntf(methodIntf); > + return this; > + } > + > public String getMethodName() { > return methodName; > } > > > > > > -- > Shawn
