Index: src/main/java/org/jboss/ejb3/session/SessionSpecContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/session/SessionSpecContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/session/SessionSpecContainer.java (working copy) @@ -15,7 +15,6 @@ import org.jboss.aop.Domain; import org.jboss.aop.MethodInfo; import org.jboss.aop.proxy.ClassProxy; -import org.jboss.aop.util.MethodHashing; import org.jboss.ejb3.Ejb3Deployment; import org.jboss.ejb3.ThreadLocalStack; import org.jboss.ejb3.annotation.LocalBinding; @@ -117,6 +116,16 @@ */ public abstract Object createProxyLocalEjb21(LocalBinding binding, String businessInterfaceType) throws Exception; + + + /* + * + * + * + * + * + */ + /** * Invokes the method described by the specified serializable method * as called from the specified proxy, using the specified arguments @@ -145,7 +154,12 @@ * Obtain the target method (advised) */ Method actualMethod = method.toMethod(this.getClassloader()); - long hash = MethodHashing.calculateHash(actualMethod); +// long hash = MethodHashing.calculateHash(actualMethod); + + + + long hash = method.hashCode(); + MethodInfo info = getAdvisor().getMethodInfo(hash); if (info == null) { @@ -157,6 +171,8 @@ SerializableMethod unadvisedSerializableMethod = new SerializableMethod(unadvisedMethod); + + // Obtain Invocation Handler //TODO Ugly, use polymorphism and get Session ID for SFSB only assert Proxy.isProxyClass(proxy.getClass()); @@ -167,15 +183,18 @@ sessionId = ((StatefulProxyInvocationHandlerBase) handler).getSessionId(); } + log.warn("\n\n\n\n\n\nUnadvised: " + unadvisedSerializableMethod + "\nInvoked: " + method+ "\n\n\n"); + + /* * Invoke directly if this is an EJB2.x Method */ - if (unadvisedMethod != null && isHomeMethod(unadvisedSerializableMethod)) + if (unadvisedMethod != null && isHomeMethod(method)) { return invokeHomeMethod(actualMethod, args); } - else if (unadvisedMethod != null && this.isEjbObjectMethod(unadvisedSerializableMethod)) + else if (unadvisedMethod != null && this.isEjbObjectMethod(method)) { return invokeEJBObjectMethod(sessionId, info, args); } @@ -476,34 +495,34 @@ return this.isHomeMethod(invokingMethod); } - /** - * @param method - * @return - * @deprecated Use isEjbObjectMethod(SerializableMethod method) - */ - @Deprecated - protected boolean isEJBObjectMethod(Method method) - { - /* - * Initialize - */ - - // Get the declaring class - Class declaringClass = method.getDeclaringClass(); - - /* - * Test if declared by EJBObject/EJBLocalObject - */ - - if (declaringClass.getName().equals(EJBObject.class.getName())) - return true; +// /** +// * @param method +// * @return +// * @deprecated Use isEjbObjectMethod(SerializableMethod method) +// */ +// @Deprecated +// protected boolean isEJBObjectMethod(Method method) +// { +// /* +// * Initialize +// */ +// +// // Get the declaring class +// Class declaringClass = method.getDeclaringClass(); +// +// /* +// * Test if declared by EJBObject/EJBLocalObject +// */ +// +// if (declaringClass.getName().equals(EJBObject.class.getName())) +// return true; +// +// if (declaringClass.getName().equals(EJBLocalObject.class.getName())) +// return true; +// +// return false; +// } - if (declaringClass.getName().equals(EJBLocalObject.class.getName())) - return true; - - return false; - } - /** * Determines whether the specified method is an EJB2.x Local * or Remote Method Index: src/main/java/org/jboss/ejb3/session/SessionContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/session/SessionContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/session/SessionContainer.java (working copy) @@ -27,9 +27,11 @@ import java.rmi.Remote; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Set; import javax.ejb.EJBHome; import javax.ejb.EJBLocalHome; @@ -55,6 +57,7 @@ import org.jboss.ejb3.annotation.LocalBinding; import org.jboss.ejb3.annotation.RemoteBinding; import org.jboss.ejb3.annotation.RemoteBindings; +import org.jboss.ejb3.common.lang.SerializableMethod; import org.jboss.ejb3.common.registrar.spi.Ejb3Registrar; import org.jboss.ejb3.common.registrar.spi.Ejb3RegistrarLocator; import org.jboss.ejb3.common.registrar.spi.NotBoundException; @@ -69,6 +72,8 @@ import org.jboss.ha.framework.server.HATarget; import org.jboss.logging.Logger; import org.jboss.metadata.ejb.jboss.JBossSessionBeanMetaData; +import org.jboss.metadata.ejb.spec.BusinessLocalsMetaData; +import org.jboss.metadata.ejb.spec.BusinessRemotesMetaData; import org.jboss.serial.io.MarshalledObjectForLocalCalls; /** @@ -79,7 +84,6 @@ */ public abstract class SessionContainer extends EJBContainer { - @SuppressWarnings("unused") private static final Logger log = Logger.getLogger(SessionContainer.class); // ------------------------------------------------------------------------------|| @@ -233,44 +237,135 @@ super.lockedStop(); } + /** + * Obtains the virtual methods for this EJB, namely, + * methods defined by any of the business, home, + * or component interfaces + */ @Override - public List getVirtualMethods() + public Set getVirtualMethods() { - List virtualMethods = new ArrayList(); + // Initialize + Set virtualMethods = new HashSet(); + try { + /* + * Remote Home + */ RemoteHome home = getAnnotation(RemoteHome.class); if (home != null) { - Method[] declaredMethods = home.value().getMethods(); - for(Method declaredMethod : declaredMethods) - virtualMethods.add(declaredMethod); - - declaredMethods = javax.ejb.EJBObject.class.getMethods(); - for(Method declaredMethod : declaredMethods) - virtualMethods.add(declaredMethod); + String homeFqn = home.value().getName(); + virtualMethods.addAll(this.getMethodsForClass(homeFqn)); } + /* + * LocalHome + */ LocalHome localHome = getAnnotation(LocalHome.class); if (localHome != null) { - Method[] declaredMethods = localHome.value().getMethods(); - for(Method declaredMethod : declaredMethods) - virtualMethods.add(declaredMethod); - - declaredMethods = javax.ejb.EJBLocalObject.class.getMethods(); - for(Method declaredMethod : declaredMethods) - virtualMethods.add(declaredMethod); + String localHomeFqn = localHome.value().getName(); + virtualMethods.addAll(this.getMethodsForClass(localHomeFqn)); } + + /* + * Business interfaces + */ + Set businessInterfaceNames = new HashSet(); + JBossSessionBeanMetaData smd = this.getMetaData(); + BusinessLocalsMetaData businessLocals = smd.getBusinessLocals(); + BusinessRemotesMetaData businessRemotes = smd.getBusinessRemotes(); + if (businessLocals != null) + { + businessInterfaceNames.addAll(businessLocals); + } + if (businessRemotes != null) + { + businessInterfaceNames.addAll(businessRemotes); + } + for(String businessInterfaceName : businessInterfaceNames) + { + virtualMethods.addAll(this.getMethodsForClass(businessInterfaceName)); + } + + /* + * Remote Component Interface + */ + String remote = smd.getRemote(); + if (remote != null && remote.trim().length() > 0) + { + virtualMethods.addAll(this.getMethodsForClass(remote)); + } + + /* + * Local Component Interface + */ + String local = smd.getLocal(); + if (local != null && local.trim().length() > 0) + { + virtualMethods.addAll(this.getMethodsForClass(local)); + } } catch (SecurityException e) { // TODO: privileged? throw new RuntimeException(e); } + + // Optionally log + if (log.isDebugEnabled()) + { + StringBuffer sb = new StringBuffer("EJB " + this.getMetaData().getEjbName() + " has Virtual Methods: \n"); + for (SerializableMethod method : virtualMethods) + { + sb.append(method); + sb.append("\n"); + } + log.debug(sb.toString()); + } + + // Return return virtualMethods; } + /** + * Returns all methods for a specified class name + * + * @param fqn + * @return + */ + private Set getMethodsForClass(String fqn) + { + // Initialize + Set methodSet = new HashSet(); + Class clazz = null; + + // Get the Class + try + { + clazz = Class.forName(fqn, false, this.getClassloader()); + } + catch (ClassNotFoundException cnfe) + { + throw new RuntimeException("Could not get methods for specified class " + fqn + " for EJB " + + this.getMetaData().getEjbName(), cnfe); + } + + // Get the methods + Method[] methods = clazz.getMethods(); + for (Method method : methods) + { + SerializableMethod serializableMethod = new SerializableMethod(method); + serializableMethod.setActualClassName(fqn); + methodSet.add(serializableMethod); + } + + // Return + return methodSet; + } + // --------------------------------------------------------------------------------|| // Contracts ----------------------------------------------------------------------|| // --------------------------------------------------------------------------------|| Index: src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/stateful/StatefulContainer.java (working copy) @@ -434,7 +434,7 @@ return invokeLocalHomeMethod(info, args); } else if (unadvisedMethod != null - && isEJBObjectMethod(unadvisedMethod)) + && isEjbObjectMethod(new SerializableMethod(unadvisedMethod))) { return invokeEJBLocalObjectMethod(id, info, args); } @@ -551,16 +551,6 @@ + ", but has been passed: " + invocation; StatefulRemoteInvocation si = (StatefulRemoteInvocation) invocation; - // Get the method hash - long methodHash = si.getMethodHash(); - log.debug("Received dynamic invocation for method with hash: " + methodHash); - - // Get the Method via MethodInfo from the Advisor - Advisor advisor = this.getAdvisor(); - MethodInfo info = advisor.getMethodInfo(methodHash); - Method unadvisedMethod = info.getMethod(); - SerializableMethod unadvisedMethodSerializable = new SerializableMethod(unadvisedMethod); - // Get the invoked method from invocation metadata Object objInvokedMethod = si.getMetaData(SessionSpecRemotingMetadata.TAG_SESSION_INVOCATION, SessionSpecRemotingMetadata.KEY_INVOKED_METHOD); @@ -569,7 +559,28 @@ + SerializableMethod.class.getName() + ", instead: " + objInvokedMethod; SerializableMethod invokedMethod = (SerializableMethod) objInvokedMethod; + // ALR TESTING + + /* + * + * + * + * + */ + + // Get the method hash +// long methodHash = si.getMethodHash(); + long methodHash = invokedMethod.hashCode(); + log.debug("Received dynamic invocation for method with hash: " + methodHash); + + // Get the Method via MethodInfo from the Advisor + Advisor advisor = this.getAdvisor(); + MethodInfo info = advisor.getMethodInfo(methodHash); + Method unadvisedMethod = info.getMethod(); + SerializableMethod unadvisedMethodSerializable = new SerializableMethod(unadvisedMethod); + + /* * Set the invoked method */ //TODO Remove when CurrentInvocation is ironed out @@ -597,11 +608,11 @@ sessionId = (Serializable) objSessionId; } - if (info != null && unadvisedMethod != null && isHomeMethod(unadvisedMethodSerializable)) + if (info != null && unadvisedMethod != null && isHomeMethod(invokedMethod)) { response = invokeHomeMethod(info, si); } - else if (info != null && unadvisedMethod != null && isEjbObjectMethod(unadvisedMethodSerializable)) + else if (info != null && unadvisedMethod != null && isEjbObjectMethod(invokedMethod)) { response = invokeEJBObjectMethod(invokedMethod, si); } Index: src/main/java/org/jboss/ejb3/service/ServiceContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/service/ServiceContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/service/ServiceContainer.java (working copy) @@ -67,6 +67,7 @@ import org.jboss.ejb3.proxy.factory.session.SessionProxyFactory; import org.jboss.ejb3.proxy.factory.session.service.ServiceRemoteProxyFactory; import org.jboss.ejb3.proxy.objectstore.ObjectStoreBindings; +import org.jboss.ejb3.proxy.remoting.SessionSpecRemotingMetadata; import org.jboss.ejb3.session.SessionContainer; import org.jboss.ejb3.stateful.StatefulContainerInvocation; import org.jboss.ejb3.timerservice.TimedObjectInvoker; @@ -490,8 +491,20 @@ ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); StatefulContainerInvocation newSi = null; + // Get the invoked method from invocation metadata + Object objInvokedMethod = invocation.getMetaData(SessionSpecRemotingMetadata.TAG_SESSION_INVOCATION, + SessionSpecRemotingMetadata.KEY_INVOKED_METHOD); + assert objInvokedMethod != null : "Invoked Method must be set on invocation metadata"; + assert objInvokedMethod instanceof SerializableMethod : "Invoked Method set on invocation metadata is not of type " + + SerializableMethod.class.getName() + ", instead: " + objInvokedMethod; + SerializableMethod invokedMethod = (SerializableMethod) objInvokedMethod; + + MethodInvocation si = (MethodInvocation) invocation; - MethodInfo info = getAdvisor().getMethodInfo(si.getMethodHash()); + + + + MethodInfo info = getAdvisor().getMethodInfo(invokedMethod.hashCode()); Method method = info.getUnadvisedMethod(); try { Index: src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/stateless/StatelessContainer.java (working copy) @@ -433,14 +433,30 @@ + ".dynamicInoke supports only " + MethodInvocation.class.getSimpleName() + ", but has been passed: " + invocation; MethodInvocation si = (MethodInvocation) invocation; + + // Get the invoked method from invocation metadata + Object objInvokedMethod = si.getMetaData(SessionSpecRemotingMetadata.TAG_SESSION_INVOCATION,SessionSpecRemotingMetadata.KEY_INVOKED_METHOD); + assert objInvokedMethod !=null : "Invoked Method must be set on invocation metadata"; + assert objInvokedMethod instanceof SerializableMethod : "Invoked Method set on invocation metadata is not of type " + SerializableMethod.class.getName() + ", instead: " + objInvokedMethod; + SerializableMethod invokedMethod = (SerializableMethod)objInvokedMethod; // Get the method hash - long methodHash = si.getMethodHash(); + long methodHash = invokedMethod.hashCode(); log.debug("Received dynamic invocation for method with hash: " + methodHash); // Get the Method via MethodInfo from the Advisor Advisor advisor = this.getAdvisor(); + if (log.isTraceEnabled()) + { + log.trace("Looking for registered method " + methodHash + " / " + invokedMethod); + } MethodInfo info = advisor.getMethodInfo(methodHash); + if(info==null) + { + throw new RuntimeException("Could not find invoked method registered w/ EJB " + + this.getMetaData().getEjbName() + ": " + methodHash + invokedMethod); + } + Method unadvisedMethod = info.getMethod(); SerializableMethod unadvisedMethodSerializable = new SerializableMethod(unadvisedMethod); @@ -453,11 +469,7 @@ */ //TODO Remove when CurrentInvocation is ironed out - // Get the invoked method from invocation metadata - Object objInvokedMethod = si.getMetaData(SessionSpecRemotingMetadata.TAG_SESSION_INVOCATION,SessionSpecRemotingMetadata.KEY_INVOKED_METHOD); - assert objInvokedMethod !=null : "Invoked Method must be set on invocation metadata"; - assert objInvokedMethod instanceof SerializableMethod : "Invoked Method set on invocation metadata is not of type " + SerializableMethod.class.getName() + ", instead: " + objInvokedMethod; - SerializableMethod invokedMethod = (SerializableMethod)objInvokedMethod; + // Set onto stack SessionSpecContainer.invokedMethod.push(invokedMethod); @@ -546,7 +558,8 @@ { rtn = invokeHomeMethod(info, si); } - else if (info != null && unadvisedMethod != null && isEJBObjectMethod(unadvisedMethod)) + else if (info != null && unadvisedMethod != null + && isEjbObjectMethod(new SerializableMethod(unadvisedMethod))) { rtn = invokeEJBObjectMethod(info, si); } Index: src/main/java/org/jboss/ejb3/EJBContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/EJBContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/EJBContainer.java (working copy) @@ -35,6 +35,7 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -73,6 +74,7 @@ import org.jboss.ejb3.annotation.SecurityDomain; import org.jboss.ejb3.annotation.defaults.PoolDefaults; import org.jboss.ejb3.aop.BeanContainer; +import org.jboss.ejb3.common.lang.SerializableMethod; import org.jboss.ejb3.common.spi.ErrorCodes; import org.jboss.ejb3.deployers.JBoss5DependencyPolicy; import org.jboss.ejb3.injection.InjectionInvocation; @@ -433,13 +435,11 @@ } /** - * Do not call, used by BeanContainer. + * Obtains all virtual methods + * * @return */ - public List getVirtualMethods() - { - return null; - } + public abstract Set getVirtualMethods(); public void setJaccContextId(String jaccContextId) { Index: src/main/java/org/jboss/ejb3/aop/BeanContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/aop/BeanContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/aop/BeanContainer.java (working copy) @@ -26,12 +26,14 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.jboss.aop.Advisor; import org.jboss.aop.Domain; import org.jboss.aop.annotation.AnnotationRepository; import org.jboss.ejb3.EJBContainer; import org.jboss.ejb3.cluster.metadata.ClusteredMetaDataBridge; +import org.jboss.ejb3.common.lang.SerializableMethod; import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor; import org.jboss.ejb3.interceptors.direct.AbstractDirectContainer; import org.jboss.ejb3.interceptors.metadata.AdditiveBeanInterceptorMetaDataBridge; @@ -180,7 +182,7 @@ return container; } - protected List getVirtualMethods() + protected Set getVirtualMethods() { return container.getVirtualMethods(); } Index: src/main/java/org/jboss/ejb3/aop/ExtendedManagedObjectAdvisor.java =================================================================== --- src/main/java/org/jboss/ejb3/aop/ExtendedManagedObjectAdvisor.java (revision 82248) +++ src/main/java/org/jboss/ejb3/aop/ExtendedManagedObjectAdvisor.java (working copy) @@ -22,12 +22,13 @@ package org.jboss.ejb3.aop; import java.lang.reflect.Method; -import java.util.List; +import java.util.Set; import org.jboss.aop.AspectManager; import org.jboss.aop.annotation.AnnotationRepository; -import org.jboss.aop.util.MethodHashing; +import org.jboss.ejb3.common.lang.SerializableMethod; import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor; +import org.jboss.logging.Logger; /** * The extended manager object advisor allows for virtual methods. @@ -39,6 +40,8 @@ */ public class ExtendedManagedObjectAdvisor extends ManagedObjectAdvisor { + private static final Logger log = Logger.getLogger(ExtendedManagedObjectAdvisor.class); + protected ExtendedManagedObjectAdvisor(BeanContainer container, String name, AspectManager manager, AnnotationRepository annotations) { super(container, name, manager, annotations); @@ -47,19 +50,28 @@ @Override protected void createMethodTables() throws Exception { - super.createMethodTables(); - List virtualMethods = getVirtualMethods(); + super.initAdvisedMethodsMap(); + + Set virtualMethods = getVirtualMethods(); if(virtualMethods != null) { - for(Method virtualMethod : virtualMethods) + for(SerializableMethod virtualMethod : virtualMethods) { - long hash = MethodHashing.methodHash(virtualMethod); - advisedMethods.put(hash, virtualMethod); + long actualClassMethodHash = this.methodHash(virtualMethod); + log.debug("Registering hash / virtual method: " + actualClassMethodHash + " / " + virtualMethod); + Method actualMethod = virtualMethod.toMethod(this.getClassLoader()); + SerializableMethod declaringClassMethod = new SerializableMethod(actualMethod); + long declaringClassMethodHash = this.methodHash(declaringClassMethod); + advisedMethods.put(actualClassMethodHash, actualMethod); + if (actualClassMethodHash != declaringClassMethodHash) + { + advisedMethods.put(declaringClassMethodHash, actualMethod); + } } } } - private List getVirtualMethods() + private Set getVirtualMethods() { return getContainer().getVirtualMethods(); } @@ -78,4 +90,35 @@ initializeMethodChain(); rebuildInterceptors(); } + + /** + * Obtains a hash for the specified method + * + * @param method + * @return + * @throws Exception + */ + protected long methodHash(SerializableMethod method) throws Exception + { + long hash = method.hashCode(); + if (log.isTraceEnabled()) + { + log.trace("Method Hash: " + hash + ", Method: " + method); + } + return hash; + } + + /** + * Obtains a hash for the specified method + * + * @param method + * @return + * @throws Exception + */ + @Override + protected long methodHash(Method method) throws Exception + { + SerializableMethod m = new SerializableMethod(method); + return this.methodHash(m); + } } Index: src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java =================================================================== --- src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java (revision 82248) +++ src/main/java/org/jboss/ejb3/mdb/MessagingContainer.java (working copy) @@ -24,6 +24,7 @@ import java.lang.reflect.Method; import java.util.Hashtable; import java.util.Map; +import java.util.Set; import javax.ejb.ActivationConfigProperty; import javax.ejb.EJBException; @@ -46,6 +47,7 @@ import org.jboss.ejb3.Ejb3Deployment; import org.jboss.ejb3.Ejb3Module; import org.jboss.ejb3.annotation.ResourceAdapter; +import org.jboss.ejb3.common.lang.SerializableMethod; import org.jboss.ejb3.jms.JMSDestinationFactory; import org.jboss.ejb3.mdb.inflow.JBossMessageEndpointFactory; import org.jboss.ejb3.proxy.factory.ProxyFactoryHelper; @@ -620,4 +622,10 @@ else return 60000; } + + @Override + public Set getVirtualMethods() + { + return null; + } } \ No newline at end of file