[jboss-cvs] JBossAS SVN: r68157 - trunk/ejb3/src/main/org/jboss/ejb3.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Dec 11 17:56:27 EST 2007
Author: ALRubinger
Date: 2007-12-11 17:56:26 -0500 (Tue, 11 Dec 2007)
New Revision: 68157
Modified:
trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java
Log:
[EJBTHREE-1156] Fixes to check "create" methods of 2.1 Home to differ depending upon Stateful/Stateless EJBs
Modified: trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java 2007-12-11 22:55:03 UTC (rev 68156)
+++ trunk/ejb3/src/main/org/jboss/ejb3/ProxyFactoryHelper.java 2007-12-11 22:56:26 UTC (rev 68157)
@@ -55,6 +55,7 @@
import org.jboss.ejb3.service.ServiceContainer;
import org.jboss.ejb3.session.SessionContainer;
import org.jboss.ejb3.stateful.StatefulContainer;
+import org.jboss.ejb3.stateless.StatelessContainer;
import org.jboss.logging.Logger;
/**
@@ -83,38 +84,43 @@
* @return the local interfaces of the container or an empty array
*/
public static Class<?>[] getLocalAndBusinessLocalInterfaces(Container container)
- {
+ {
// Initialize
Set<Class<?>> localAndBusinessLocalInterfaces = new HashSet<Class<?>>();
-
+
// Obtain Bean Class
Class<?> beanClass = container.getBeanClass();
-
+
// Obtain @Local
Local localAnnotation = ((EJBContainer) container).getAnnotation(Local.class);
// Obtain @LocalHome
- LocalHome localHomeAnnotation = ((EJBContainer)container).getAnnotation(LocalHome.class);
-
+ LocalHome localHomeAnnotation = ((EJBContainer) container).getAnnotation(LocalHome.class);
+
// Obtain @Remote
Remote remoteAnnotation = ((EJBContainer) container).getAnnotation(Remote.class);
-
+
// Obtain Remote and Business Remote interfaces
Class<?>[] remoteAndBusinessRemoteInterfaces = ProxyFactoryHelper.getRemoteAndBusinessRemoteInterfaces(container);
// Obtain all business interfaces from the bean class
Set<Class<?>> businessInterfacesImplementedByBeanClass = ProxyFactoryHelper.getBusinessInterfaces(beanClass);
-
+
// Obtain all business interfaces directly implemented by the bean class (not including supers)
- Set<Class<?>> businessInterfacesDirectlyImplementedByBeanClass = ProxyFactoryHelper.getBusinessInterfaces(beanClass,false);
-
+ Set<Class<?>> businessInterfacesDirectlyImplementedByBeanClass = ProxyFactoryHelper.getBusinessInterfaces(
+ beanClass, false);
+
+ // Determine whether Stateful or Stateless
+ boolean isStateless = (container instanceof StatelessContainer) ? true : false;
+
// EJBTHREE-1127
// Determine local interface from return value of "create" in Local Home
- if(localHomeAnnotation!=null)
+ if (localHomeAnnotation != null)
{
- localAndBusinessLocalInterfaces.addAll(ProxyFactoryHelper.getReturnTypesFromCreateMethods(localHomeAnnotation.value()));
+ localAndBusinessLocalInterfaces.addAll(ProxyFactoryHelper.getReturnTypesFromCreateMethods(localHomeAnnotation
+ .value(), isStateless));
}
-
+
// For each of the business interfaces implemented by the bean class
for (Class<?> clazz : businessInterfacesImplementedByBeanClass)
{
@@ -125,34 +131,35 @@
localAndBusinessLocalInterfaces.add(clazz);
}
}
-
+
// EJBTHREE-1062
// EJB 3 Core Specification 4.6.6
// If bean class implements a single interface, that interface is assumed to be the
// business interface of the bean. This business interface will be a local interface unless the
// interface is designated as a remote business interface by use of the Remote
// annotation on the bean class or interface or by means of the deployment descriptor.
- if (businessInterfacesDirectlyImplementedByBeanClass.size() == 1 && localAndBusinessLocalInterfaces.size()==0)
+ if (businessInterfacesDirectlyImplementedByBeanClass.size() == 1 && localAndBusinessLocalInterfaces.size() == 0)
{
// Obtain the implemented interface
Class<?> singleInterface = businessInterfacesDirectlyImplementedByBeanClass.iterator().next();
-
+
// If not explicitly marked as @Remote, and is a valid business interface
- if (remoteAnnotation == null && singleInterface.getAnnotation(Remote.class)==null)
+ if (remoteAnnotation == null && singleInterface.getAnnotation(Remote.class) == null)
{
// Return the implemented interface, adding to the container
- Class<?>[] returnValue = new Class[]{singleInterface};
+ Class<?>[] returnValue = new Class[]
+ {singleInterface};
Local li = new LocalImpl(returnValue);
((EJBContainer) container).getAnnotations().addClassAnnotation(Local.class, li);
return returnValue;
}
}
-
+
// @Local was defined
if (localAnnotation != null)
{
// If @Local has no value or empty value
- if(localAnnotation.value()==null || localAnnotation.value().length==0)
+ if (localAnnotation.value() == null || localAnnotation.value().length == 0)
{
// If @Local is defined with no value and there are no business interfaces
if (businessInterfacesImplementedByBeanClass.size() == 0)
@@ -193,7 +200,7 @@
// Add to the list of locals
localAndBusinessLocalInterfaces.add(clazz);
}
-
+
// For each of the business interfaces implemented by the bean class
for (Class<?> clazz : businessInterfacesImplementedByBeanClass)
{
@@ -204,9 +211,9 @@
localAndBusinessLocalInterfaces.add(clazz);
}
}
- }
+ }
}
-
+
// If local interfaces have been defined/discovered
if (localAndBusinessLocalInterfaces.size() > 0)
{
@@ -223,7 +230,7 @@
}
}
}
-
+
// Return local interfaces, first adding to the container
Class<?>[] rtn = localAndBusinessLocalInterfaces.toArray(new Class<?>[]
{});
@@ -246,9 +253,10 @@
+ container.getEjbName());
}
-
+
// No local or business local interfaces discovered
- return new Class<?>[]{};
+ return new Class<?>[]
+ {};
}
/**
@@ -265,9 +273,9 @@
public static Set<Class<?>> getBusinessInterfaces(Class<?> beanClass)
{
// Obtain all business interfaces implemented by this bean class and its superclasses
- return ProxyFactoryHelper.getBusinessInterfaces(beanClass, new HashSet<Class<?>>());
+ return ProxyFactoryHelper.getBusinessInterfaces(beanClass, new HashSet<Class<?>>());
}
-
+
/**
* Resolve the potential business interfaces on an enterprise bean.
* Returns all interfaces implemented by this class and, optionally, its supers which
@@ -285,13 +293,14 @@
// Obtain all business interfaces implemented by this bean class and optionally, its superclass
return ProxyFactoryHelper.getBusinessInterfaces(beanClass, new HashSet<Class<?>>(), includeSupers);
}
-
+
private static Set<Class<?>> getBusinessInterfaces(Class<?> beanClass, Set<Class<?>> interfaces)
{
return ProxyFactoryHelper.getBusinessInterfaces(beanClass, interfaces, true);
}
-
- private static Set<Class<?>> getBusinessInterfaces(Class<?> beanClass, Set<Class<?>> interfaces, boolean includeSupers)
+
+ private static Set<Class<?>> getBusinessInterfaces(Class<?> beanClass, Set<Class<?>> interfaces,
+ boolean includeSupers)
{
/*
* 4.6.6:
@@ -299,22 +308,22 @@
* more than one interface: java.io.Serializable; java.io.Externalizable;
* any of the interfaces defined by the javax.ejb package.
*/
- for(Class<?> intf : beanClass.getInterfaces())
+ for (Class<?> intf : beanClass.getInterfaces())
{
- if(intf.equals(java.io.Externalizable.class))
+ if (intf.equals(java.io.Externalizable.class))
continue;
- if(intf.equals(java.io.Serializable.class))
+ if (intf.equals(java.io.Serializable.class))
continue;
- if(intf.getName().startsWith("javax.ejb"))
+ if (intf.getName().startsWith("javax.ejb"))
continue;
-
+
// FIXME Other aop frameworks might add other interfaces, this should really be configurable
- if(intf.getName().startsWith("org.jboss.aop"))
+ if (intf.getName().startsWith("org.jboss.aop"))
continue;
-
+
interfaces.add(intf);
}
-
+
// If there's no superclass, or we shouldn't check the superclass, return
if (!includeSupers || beanClass.getSuperclass() == null)
{
@@ -330,24 +339,28 @@
public static Class<?> getLocalHomeInterface(Container container)
{
LocalHome li = ((EJBContainer) container).getAnnotation(javax.ejb.LocalHome.class);
- if (li != null) return li.value();
+ if (li != null)
+ return li.value();
return null;
}
public static Class<?> getRemoteHomeInterface(Container container)
{
RemoteHome li = ((EJBContainer) container).getAnnotation(javax.ejb.RemoteHome.class);
- if (li != null) return li.value();
+ if (li != null)
+ return li.value();
return null;
}
public static boolean publishesInterface(Container container, Class<?> businessInterface)
{
- if (!(container instanceof SessionContainer)) return false;
+ if (!(container instanceof SessionContainer))
+ return false;
Class<?>[] remotes = getRemoteAndBusinessRemoteInterfaces(container);
for (Class<?> intf : remotes)
{
- if (intf.getName().equals(businessInterface.getName())) return true;
+ if (intf.getName().equals(businessInterface.getName()))
+ return true;
}
Class<?> remoteHome = getRemoteHomeInterface(container);
@@ -390,12 +403,12 @@
{
assert container != null : "container is null";
assert businessInterface != null : "businessInterface is null";
-
+
// Initialize to defaults of remote and not home
String jndiName = null;
boolean isHome = false;
boolean isLocal = false;
-
+
// Determine if remote
Class<?>[] remotes = ProxyFactoryHelper.getRemoteAndBusinessRemoteInterfaces(container);
for (Class<?> clazz : remotes)
@@ -403,22 +416,22 @@
if (clazz.getName().equals(businessInterface.getName()))
{
// Check for declared @RemoteBindings
- RemoteBindings bindings = ((EJBContainer)container).getAnnotation(RemoteBindings.class);
+ RemoteBindings bindings = ((EJBContainer) container).getAnnotation(RemoteBindings.class);
if (bindings != null)
{
// Encountered, return
return bindings.value()[0].jndiBinding();
}
// Check for declared @RemoteBinding
- RemoteBinding binding = ((EJBContainer)container).getAnnotation(RemoteBinding.class);
- if(binding!=null)
+ RemoteBinding binding = ((EJBContainer) container).getAnnotation(RemoteBinding.class);
+ if (binding != null)
{
// Encountered, return
return binding.jndiBinding();
}
}
}
-
+
// Determine if remote home
Class<?> remoteHome = getRemoteHomeInterface(container);
if (remoteHome != null)
@@ -426,13 +439,13 @@
if (businessInterface.getName().equals(remoteHome.getName()))
{
// Check for declared @RemoteHomeBinding
- RemoteHomeBinding binding = ((EJBContainer)container).getAnnotation(RemoteHomeBinding.class);
- if(binding!=null)
+ RemoteHomeBinding binding = ((EJBContainer) container).getAnnotation(RemoteHomeBinding.class);
+ if (binding != null)
{
// Encountered, return
return binding.jndiBinding();
- }
-
+ }
+
// Set home for policy
isHome = true;
}
@@ -445,13 +458,13 @@
if (businessInterface.getName().equals(localHome.getName()))
{
// Check for declared @LocalHomeBinding
- LocalHomeBinding binding = ((EJBContainer)container).getAnnotation(LocalHomeBinding.class);
- if(binding!=null)
+ LocalHomeBinding binding = ((EJBContainer) container).getAnnotation(LocalHomeBinding.class);
+ if (binding != null)
{
// Encountered, return
return binding.jndiBinding();
}
-
+
// Set local and home for policy
isHome = true;
isLocal = true;
@@ -465,36 +478,36 @@
if (clazz.getName().equals(businessInterface.getName()))
{
// Check for declared @LocalBinding
- LocalBinding binding = ((EJBContainer)container).getAnnotation(LocalBinding.class);
- if(binding!=null)
+ LocalBinding binding = ((EJBContainer) container).getAnnotation(LocalBinding.class);
+ if (binding != null)
{
// Encountered, return
return binding.jndiBinding();
}
-
+
// Set local for policy
isLocal = true;
}
}
-
+
// If JNDI Name has not been explicitly specified, use policy
if (jndiName == null)
{
// Log
log.debug("JNDI name has not been explicitly set for EJB " + container.getEjbName() + ", interface "
+ businessInterface.getName());
-
+
// Set JNDI name
Ejb3DeploymentSummary summary = ProxyFactoryHelper.getDeploymentSummaryFromContainer(container);
summary.setHome(isHome);
summary.setLocal(isLocal);
jndiName = ProxyFactoryHelper.getJndiBindingPolicy(container).getJndiName(summary);
}
-
+
// Return
return jndiName;
}
-
+
/**
* Returns all local interfaces in the specified container; interfaces
* marked as "local" via either annotation or XML and extending EJBLocalObject
@@ -507,7 +520,7 @@
return ProxyFactoryHelper.getInterfacesAssignableFromClass(ProxyFactoryHelper
.getLocalAndBusinessLocalInterfaces(container), EJBLocalObject.class, true);
}
-
+
/**
* Returns all remote interfaces in the specified container; interfaces
* marked as "remote" via either annotation or XML and extending EJBObject
@@ -520,7 +533,7 @@
return ProxyFactoryHelper.getInterfacesAssignableFromClass(ProxyFactoryHelper
.getRemoteAndBusinessRemoteInterfaces(container), EJBObject.class, true);
}
-
+
/**
* Returns all local business interfaces in the specified container; interfaces
* marked as "local" via either annotation or XML and not extending EJBLocalObject
@@ -533,7 +546,7 @@
return ProxyFactoryHelper.getInterfacesAssignableFromClass(ProxyFactoryHelper
.getLocalAndBusinessLocalInterfaces(container), EJBLocalObject.class, false);
}
-
+
/**
* Returns all remote business interfaces in the specified container; interfaces
* marked as "remote" via either annotation or XML and not extending EJBObject
@@ -546,7 +559,7 @@
return ProxyFactoryHelper.getInterfacesAssignableFromClass(ProxyFactoryHelper
.getRemoteAndBusinessRemoteInterfaces(container), EJBObject.class, false);
}
-
+
/**
* Returns an subset of the specified array of interfaces either
* assignable to or not assignable to the specified class, depending
@@ -557,7 +570,7 @@
* @param assignable
* @return
*/
- private static Class<?>[] getInterfacesAssignableFromClass(Class<?>[] interfaces,Class<?> clazz,boolean assignable)
+ private static Class<?>[] getInterfacesAssignableFromClass(Class<?>[] interfaces, Class<?> clazz, boolean assignable)
{
// Initialize
List<Class<?>> subset = new ArrayList<Class<?>>();
@@ -597,6 +610,7 @@
RemoteHome remoteHomeAnnotation = ((EJBContainer) container).getAnnotation(RemoteHome.class);
Set<Class<?>> remoteAndRemoteBusinessInterfaces = new HashSet<Class<?>>();
Class<?> beanClass = container.getBeanClass();
+ boolean isStateless = (container instanceof StatelessContainer) ? true : false;
// Obtain business interfaces
Class<?>[] businessInterfaces = ProxyFactoryHelper.getBusinessInterfaces(beanClass).toArray(new Class[]
@@ -606,8 +620,8 @@
// Determine remote interface from return value of "create" in Remote Home
if (remoteHomeAnnotation != null)
{
- remoteAndRemoteBusinessInterfaces
- .addAll(ProxyFactoryHelper.getReturnTypesFromCreateMethods(remoteHomeAnnotation.value()));
+ remoteAndRemoteBusinessInterfaces.addAll(ProxyFactoryHelper.getReturnTypesFromCreateMethods(
+ remoteHomeAnnotation.value(), isStateless));
}
// If @Remote is not defined
@@ -676,23 +690,26 @@
// No remotes were found
else
{
- return new Class<?>[]{};
+ return new Class<?>[]
+ {};
}
}
-
-
+
/**
- * Obtains the return types declared by the "create" methods for the specified home interface
+ * Obtains the return types declared by the "create" methods for the specified home interface.
*
* @param homeInterface
+ * @param isStateless Flag to indicate whether this is for a Stateful or Stateless container
* @return
*/
- private static Set<Class<?>> getReturnTypesFromCreateMethods(Class<?> homeInterface)
+ private static Set<Class<?>> getReturnTypesFromCreateMethods(Class<?> homeInterface, boolean isStateless)
{
// Ensure we've been passed a Home or LocalHome interface (Developers only)
assert (EJBHome.class.isAssignableFrom(homeInterface) || EJBLocalHome.class.isAssignableFrom(homeInterface));
-
- if(!EJBHome.class.isAssignableFrom(homeInterface) && !EJBLocalHome.class.isAssignableFrom(homeInterface)){
+
+ // Ensure we've been passed a Home or LocalHome interface (End-User)
+ if (!EJBHome.class.isAssignableFrom(homeInterface) && !EJBLocalHome.class.isAssignableFrom(homeInterface))
+ {
throw new RuntimeException("Declared EJB 2.1 Home Interface " + homeInterface.getName() + " does not extend "
+ EJBHome.class.getName() + " or " + EJBLocalHome.class.getName()
+ " as required by EJB 3.0 Core Specification 4.6.8 and 4.6.10");
@@ -700,17 +717,51 @@
// Initialize
Set<Class<?>> types = new HashSet<Class<?>>();
-
- // Obtain all "create<METHOD>" methods
- List<Method> createMethods = ClassHelper.getAllMethodsByPrefix(homeInterface, "create");
- if(createMethods.size() == 0)
+ List<Method> createMethods = null;
+
+ // If for a Stateless Container
+ if (isStateless)
{
+ // Initialize error message
+ String specViolationErrorMessage = "EJB 3.0 Specification Violation (4.6.8 Bullet 4, 4.6.10 Bullet 4): \""
+ + "A stateless session bean must define exactly one create method with no arguments." + "\"; found in "
+ + homeInterface.getName();
+
+ // Get all methods with signature "create"
+ createMethods = new ArrayList<Method>();
+ try
+ {
+ createMethods.add(homeInterface.getMethod("create", new Class<?>[]
+ {}));
+ }
+ // EJB 3.0 Specification 4.6.8 Bullet 4 Violation
+ // EJBTHREE-1156
+ catch (NoSuchMethodException e)
+ {
+ throw new RuntimeException(specViolationErrorMessage);
+ }
+
+ // Ensure only one create method is defined
+ // EJB 3.0 Specification 4.6.8 Bullet 4 Violation
+ // EJBTHREE-1156
+ if (createMethods.size() > 0)
+ {
+ throw new RuntimeException(specViolationErrorMessage);
+ }
+ }
+ else
+ {
+ // Obtain all "create<METHOD>" methods
+ createMethods = ClassHelper.getAllMethodsByPrefix(homeInterface, "create");
+ }
+ if (createMethods.size() == 0)
+ {
throw new RuntimeException("EJB 3.0 Core Specification Violation (4.6.8 Bullet 5): EJB2.1 Home Interface "
+ homeInterface + " does not declare a \'create<METHOD>\' method");
}
-
+
// Add all return types
- for(Method method : createMethods)
+ for (Method method : createMethods)
{
types.add(method.getReturnType());
}
@@ -724,11 +775,12 @@
String clientBindUrl = binding.clientBindUrl();
if (clientBindUrl.trim().length() == 0)
{
- ObjectName connectionON = new ObjectName("jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3");
+ ObjectName connectionON = new ObjectName(
+ "jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3");
KernelAbstraction kernelAbstraction = KernelAbstractionFactory.getInstance();
try
{
- clientBindUrl = (String)kernelAbstraction.getAttribute(connectionON, "InvokerLocator");
+ clientBindUrl = (String) kernelAbstraction.getAttribute(connectionON, "InvokerLocator");
if (clientBindUrl == null)
clientBindUrl = RemoteProxyFactory.DEFAULT_CLIENT_BINDING;
}
@@ -737,20 +789,20 @@
clientBindUrl = RemoteProxyFactory.DEFAULT_CLIENT_BINDING;
}
}
-
+
return clientBindUrl;
}
-
+
public static String getHomeJndiName(Container container)
{
// Initialize
Advisor advisor = (Advisor) container;
-
+
// Use explicitly-specified binding, if defined
- RemoteHomeBinding binding = (RemoteHomeBinding)advisor.resolveAnnotation(RemoteHomeBinding.class);
+ RemoteHomeBinding binding = (RemoteHomeBinding) advisor.resolveAnnotation(RemoteHomeBinding.class);
if (binding != null)
return binding.jndiBinding();
-
+
// Use Default JNDI Binding Policy
return ProxyFactoryHelper.getJndiBindingPolicy(container).getDefaultRemoteHomeJndiName(
ProxyFactoryHelper.getDeploymentSummaryFromContainer(container));
@@ -760,9 +812,9 @@
{
// Initialize
Advisor advisor = (Advisor) container;
-
+
// Use explicitly-specified binding, if defined
- LocalHomeBinding binding = (LocalHomeBinding)advisor.resolveAnnotation(LocalHomeBinding.class);
+ LocalHomeBinding binding = (LocalHomeBinding) advisor.resolveAnnotation(LocalHomeBinding.class);
if (binding != null)
return binding.jndiBinding();
@@ -770,7 +822,7 @@
return ProxyFactoryHelper.getJndiBindingPolicy(container).getDefaultLocalHomeJndiName(
ProxyFactoryHelper.getDeploymentSummaryFromContainer(container));
}
-
+
public static String getLocalJndiName(Container container)
{
return getLocalJndiName(container, true);
@@ -780,11 +832,10 @@
{
// Initialize
Advisor advisor = (Advisor) container;
-
+
// See if local binding is explicitly-defined
- LocalBinding localBinding = (LocalBinding) advisor
- .resolveAnnotation(LocalBinding.class);
-
+ LocalBinding localBinding = (LocalBinding) advisor.resolveAnnotation(LocalBinding.class);
+
// If none specified
if (localBinding == null)
{
@@ -803,7 +854,7 @@
return localBinding.jndiBinding();
}
}
-
+
public static String getRemoteJndiName(Container container)
{
return getRemoteJndiName(container, true);
@@ -812,8 +863,7 @@
public static String getRemoteJndiName(Container container, boolean check)
{
Advisor advisor = (Advisor) container;
- RemoteBinding binding = (RemoteBinding) advisor
- .resolveAnnotation(RemoteBinding.class);
+ RemoteBinding binding = (RemoteBinding) advisor.resolveAnnotation(RemoteBinding.class);
return getRemoteJndiName(container, binding);
}
@@ -863,7 +913,7 @@
return ProxyFactoryHelper.getJndiBindingPolicy(container).getDefaultRemoteJndiName(
ProxyFactoryHelper.getDeploymentSummaryFromContainer(container));
}
-
+
/**
* Obtains the JNDI Binding Policy for the specified container
*
@@ -876,7 +926,7 @@
EJBContainer ejbContainer = (EJBContainer) container;
JndiBindingPolicy bindingPolicy = ejbContainer.getAnnotation(JndiBindingPolicy.class);
Class<? extends DefaultJndiBindingPolicy> policy = null;
- if(bindingPolicy != null)
+ if (bindingPolicy != null)
policy = bindingPolicy.policy();
else
{
@@ -899,7 +949,7 @@
throw new RuntimeException(e);
}
}
-
+
private static Ejb3DeploymentSummary getDeploymentSummaryFromContainer(Container container)
{
// Construct Deployment Summary
More information about the jboss-cvs-commits
mailing list