You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2009/04/16 05:12:08 UTC

svn commit: r765456 - in /openejb/trunk/openejb3: assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/ assembly/openejb-tomcat/openejb-tomcat-common/src/main/java/org/apache/openejb/tomcat/common/ container/...

Author: dblevins
Date: Thu Apr 16 03:12:08 2009
New Revision: 765456

URL: http://svn.apache.org/viewvc?rev=765456&view=rev
Log:
Part 1 of OPENEJB-1018: Support for exposing a single interface as @WebService, @Remote, and @Local

Added:
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/MappedNameTest.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/UberInterfaceTest.java
Modified:
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-common/src/main/java/org/apache/openejb/tomcat/common/EjbFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbReferenceInfo.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyEjbReference.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationPrinter.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/InheritenceTest.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/EJB.java
    openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java Thu Apr 16 03:12:08 2009
@@ -182,10 +182,10 @@
 
         ejb.setProperty(Constants.FACTORY, EjbFactory.class.getName());
         ejb.setProperty(NAME, ref.referenceName);
-        ejb.setHome(ref.homeType);
-        ejb.setRemote(ref.interfaceType);
+        ejb.setHome(ref.homeClassName);
+        ejb.setRemote(ref.interfaceClassName);
         ejb.setLink(null);
-        ejb.setType(ref.interfaceType);
+        ejb.setType(ref.interfaceClassName);
         if (useCrossClassLoaderRef) {
             ejb.setProperty(EXTERNAL, "" + ref.externalReference);
         }
@@ -223,11 +223,11 @@
 
         ejb.setProperty(Constants.FACTORY, EjbFactory.class.getName());
         ejb.setProperty(NAME, ref.referenceName);
-        ejb.setHome(ref.homeType);
+        ejb.setHome(ref.homeClassName);
         ejb.setRemote(null);
-        ejb.setProperty(LOCAL, ref.interfaceType);
+        ejb.setProperty(LOCAL, ref.interfaceClassName);
         ejb.setLink(null);
-        ejb.setType(ref.interfaceType);
+        ejb.setType(ref.interfaceClassName);
 
         if (ref.ejbDeploymentId != null) {
             ejb.setProperty(DEPLOYMENT_ID, ref.ejbDeploymentId);

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-common/src/main/java/org/apache/openejb/tomcat/common/EjbFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-common/src/main/java/org/apache/openejb/tomcat/common/EjbFactory.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-common/src/main/java/org/apache/openejb/tomcat/common/EjbFactory.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-common/src/main/java/org/apache/openejb/tomcat/common/EjbFactory.java Thu Apr 16 03:12:08 2009
@@ -26,6 +26,8 @@
 import static org.apache.openejb.tomcat.common.NamingUtil.REMOTE;
 import static org.apache.openejb.tomcat.common.NamingUtil.getProperty;
 import static org.apache.openejb.tomcat.common.NamingUtil.isPropertyTrue;
+import org.apache.openejb.InterfaceType;
+import org.apache.openejb.assembler.classic.JndiBuilder;
 
 import javax.naming.Context;
 import javax.naming.Name;
@@ -62,14 +64,16 @@
         if (deploymentId == null) throw new NamingException("ejb-ref deploymentId is null");
 
         // get and verify interface type
+        InterfaceType type = InterfaceType.BUSINESS_REMOTE;
         String interfaceType = getProperty(reference, REMOTE);
         if (interfaceType == null) {
+            type = InterfaceType.BUSINESS_LOCAL;
             interfaceType = getProperty(reference, LOCAL);
         }
         if (interfaceType == null) throw new NamingException("ejb-ref interface type is null");
 
         // build jndi name using the deploymentId and interface type
-        jndiName = "java:openejb/Deployment/" + deploymentId + "/" + interfaceType;
+        jndiName = "java:openejb/Deployment/" + JndiBuilder.format(deploymentId, interfaceType, type);
         return jndiName;
     }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbReferenceInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbReferenceInfo.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbReferenceInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbReferenceInfo.java Thu Apr 16 03:12:08 2009
@@ -19,8 +19,8 @@
 public class EjbReferenceInfo extends InjectableInfo {
 
     public String referenceName;
-    public String homeType;
-    public String interfaceType;
+    public String homeClassName;
+    public String interfaceClassName;
     public String ejbDeploymentId;
     public boolean externalReference;
     public String link;

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java Thu Apr 16 03:12:08 2009
@@ -270,7 +270,10 @@
                 ObjectReference ref = new ObjectReference(deployment.getEJBHome());
                 bind(name, ref, bindings, beanInfo, homeInterface);
 
-                name = "openejb/Deployment/" + deployment.getDeploymentID() + "/" + deployment.getRemoteInterface().getName();
+                name = "openejb/Deployment/" + format(deployment.getDeploymentID(), deployment.getRemoteInterface().getName());
+                bind(name, ref, bindings, beanInfo, homeInterface);
+
+                name = "openejb/Deployment/" + format(deployment.getDeploymentID(), deployment.getRemoteInterface().getName(), InterfaceType.EJB_OBJECT);
                 bind(name, ref, bindings, beanInfo, homeInterface);
             }
         } catch (NamingException e) {
@@ -285,7 +288,10 @@
                 ObjectReference ref = new ObjectReference(deployment.getEJBLocalHome());
                 bind(name, ref, bindings, beanInfo, localHomeInterface);
 
-                name = "openejb/Deployment/" + deployment.getDeploymentID() + "/" + deployment.getLocalInterface().getName();
+                name = "openejb/Deployment/" + format(deployment.getDeploymentID(), deployment.getLocalInterface().getName());
+                bind(name, ref, bindings, beanInfo, localHomeInterface);
+
+                name = "openejb/Deployment/" + format(deployment.getDeploymentID(), deployment.getLocalInterface().getName(), InterfaceType.EJB_LOCAL);
                 bind(name, ref, bindings, beanInfo, localHomeInterface);
             }
         } catch (NamingException e) {
@@ -302,7 +308,9 @@
                 DeploymentInfo.BusinessLocalHome home = deployment.getBusinessLocalHome(interfaces);
                 BusinessLocalReference ref = new BusinessLocalReference(home);
 
-                String internalName = "openejb/Deployment/" + deployment.getDeploymentID() + "/" + interfce.getName();
+                optionalBind(bindings, ref, "openejb/Deployment/" + format(deployment.getDeploymentID(), interfce.getName()));
+
+                String internalName = "openejb/Deployment/" + format(deployment.getDeploymentID(), interfce.getName(), InterfaceType.BUSINESS_LOCAL);
                 bind(internalName, ref, bindings, beanInfo, interfce);
 
                 String externalName = "openejb/ejb/" + strategy.getName(interfce, JndiNameStrategy.Interface.BUSINESS_LOCAL);
@@ -323,7 +331,9 @@
                 DeploymentInfo.BusinessRemoteHome home = deployment.getBusinessRemoteHome(interfaces);
                 BusinessRemoteReference ref = new BusinessRemoteReference(home);
 
-                String internalName = "openejb/Deployment/" + deployment.getDeploymentID() + "/" + interfce.getName();
+                optionalBind(bindings, ref, "openejb/Deployment/" + format(deployment.getDeploymentID(), interfce.getName(), null));
+
+                String internalName = "openejb/Deployment/" + format(deployment.getDeploymentID(), interfce.getName(), InterfaceType.BUSINESS_REMOTE);
                 bind(internalName, ref, bindings, beanInfo, interfce);
 
                 String externalName = "openejb/ejb/" + strategy.getName(interfce, JndiNameStrategy.Interface.BUSINESS_REMOTE);
@@ -348,6 +358,25 @@
         }
     }
 
+    private void optionalBind(Bindings bindings, Reference ref, String name) throws NamingException {
+        try {
+            context.bind(name, ref);
+            bindings.add(name);
+        } catch (NamingException okIfBindFails) {
+        }
+    }
+
+    public static String format(Object deploymentId, String interfaceClassName) {
+        return format((String) deploymentId, interfaceClassName, null);
+    }
+
+    public static String format(Object deploymentId, String interfaceClassName, InterfaceType interfaceType) {
+        return format((String) deploymentId, interfaceClassName, interfaceType);
+    }
+
+    public static String format(String deploymentId, String interfaceClassName, InterfaceType interfaceType) {
+        return deploymentId + "/" + interfaceClassName + (interfaceType == null ? "" : "!" + interfaceType.getSpecName());
+    }
 
     private void bind(String name, Reference ref, Bindings bindings, EnterpriseBeanInfo beanInfo, Class intrface) throws NamingException {
 
@@ -362,7 +391,6 @@
 
             try {
                 context.bind(name, ref);
-
                 bindings.add(name);
 
                 beanInfo.jndiNames.add(externalName);

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java Thu Apr 16 03:12:08 2009
@@ -18,6 +18,7 @@
 
 import org.apache.openejb.Injection;
 import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.InterfaceType;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.core.CoreUserTransaction;
 import org.apache.openejb.core.TransactionSynchronizationRegistryWrapper;
@@ -27,8 +28,6 @@
 import org.apache.openejb.core.ivm.naming.JaxWsServiceReference;
 import org.apache.openejb.core.ivm.naming.JndiReference;
 import org.apache.openejb.core.ivm.naming.JndiUrlReference;
-import org.apache.openejb.core.ivm.naming.NameNode;
-import org.apache.openejb.core.ivm.naming.ParsedName;
 import org.apache.openejb.core.ivm.naming.PersistenceContextReference;
 import org.apache.openejb.core.ivm.naming.Reference;
 import org.apache.openejb.core.ivm.naming.SystemComponentReference;
@@ -54,7 +53,6 @@
 import javax.naming.NamingException;
 import javax.persistence.EntityManagerFactory;
 import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
 import javax.transaction.UserTransaction;
 import javax.xml.ws.Service;
 import javax.xml.ws.WebServiceContext;
@@ -181,7 +179,7 @@
             } else if (referenceInfo.ejbDeploymentId == null){
                 reference = new LazyEjbReference(new Ref(referenceInfo), moduleUri, useCrossClassLoaderRef);
             } else {
-                String jndiName = "java:openejb/Deployment/" + referenceInfo.ejbDeploymentId + "/" + referenceInfo.interfaceType;
+                String jndiName = "java:openejb/Deployment/" + JndiBuilder.format(referenceInfo.ejbDeploymentId, referenceInfo.interfaceClassName, InterfaceType.BUSINESS_REMOTE);
                 if (useCrossClassLoaderRef && referenceInfo.externalReference) {
                     reference = new CrossClassLoaderJndiReference(jndiName);
                 } else {
@@ -200,7 +198,7 @@
             } else if (referenceInfo.ejbDeploymentId == null){
                 reference = new LazyEjbReference(new Ref(referenceInfo), moduleUri, false);
             } else {
-                String jndiName = "java:openejb/Deployment/" + referenceInfo.ejbDeploymentId + "/" + referenceInfo.interfaceType;
+                String jndiName = "java:openejb/Deployment/" + JndiBuilder.format(referenceInfo.ejbDeploymentId, referenceInfo.interfaceClassName, InterfaceType.BUSINESS_LOCAL);
                 reference = new IntraVmJndiReference(jndiName);
             }
             bindings.put(normalize(referenceInfo.referenceName), reference);
@@ -504,11 +502,11 @@
         }
 
         public String getHome() {
-            return info.homeType;
+            return info.homeClassName;
         }
 
         public String getInterface() {
-            return info.interfaceType;
+            return info.interfaceClassName;
         }
 
         public String getMappedName() {
@@ -522,7 +520,7 @@
         public EjbResolver.Type getRefType() {
             if (info instanceof EjbLocalReferenceInfo){
                 return EjbResolver.Type.LOCAL;
-            } else if (info.homeType != null) {
+            } else if (info.homeClassName != null) {
                 return EjbResolver.Type.REMOTE;
             } else {
                 return EjbResolver.Type.UNKNOWN;

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyEjbReference.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyEjbReference.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyEjbReference.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyEjbReference.java Thu Apr 16 03:12:08 2009
@@ -80,7 +80,13 @@
             throw new NameNotFoundException(message);
         }
 
-        String jndiName = "java:openejb/Deployment/" + deploymentId + "/" + info.getInterface();
+        InterfaceType type = null;
+        switch (info.getRefType()){
+            case LOCAL: type = InterfaceType.BUSINESS_LOCAL; break;
+            case REMOTE: type = InterfaceType.BUSINESS_REMOTE; break;
+        }
+
+        String jndiName = "java:openejb/Deployment/" + JndiBuilder.format(deploymentId, info.getInterface(), type);
 
         if (useCrossClassLoaderRef && isRemote(deploymentInfo)) {
             reference = new CrossClassLoaderJndiReference(jndiName);

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java Thu Apr 16 03:12:08 2009
@@ -18,6 +18,7 @@
 
 import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.core.webservices.JaxWsUtils;
 import org.apache.openejb.finder.ClassFinder;
 import org.apache.openejb.jee.ActivationConfig;
@@ -82,6 +83,7 @@
 import org.apache.openejb.jee.TransactionType;
 import org.apache.openejb.jee.WebApp;
 import org.apache.openejb.jee.WebserviceDescription;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
 import static org.apache.openejb.util.Join.join;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
@@ -537,6 +539,7 @@
                 "double", "java.lang.Double",
                 "java.lang.String"
         ));
+        private static final String STRICT_INTERFACE_DECLARATION = "openejb.strict.interface.declaration";
 
         public AppModule deploy(AppModule appModule) throws OpenEJBException {
             for (EjbModule ejbModule : appModule.getEjbModules()) {
@@ -1307,20 +1310,25 @@
             ValidationContext validation = ejbModule.getValidation();
             String ejbName = sessionBean.getEjbName();
 
+            boolean strict = getProperty(ejbModule, STRICT_INTERFACE_DECLARATION, false + "").equalsIgnoreCase("true");
+
             for (Class<?> clazz : ancestors(beanClass)) {
                 /*
                  * Collect all interfaces explicitly declared via xml.
                  * We will subtract these from the interfaces implemented
                  * by the bean and do annotation scanning on the remainder.
                  */
-                List<String> declared = new ArrayList<String>();
-                declared.addAll(sessionBean.getBusinessLocal());
-                declared.addAll(sessionBean.getBusinessRemote());
-                declared.add(sessionBean.getHome());
-                declared.add(sessionBean.getRemote());
-                declared.add(sessionBean.getLocalHome());
-                declared.add(sessionBean.getLocal());
-                declared.add(sessionBean.getServiceEndpoint());
+                List<String> xmlDeclared = new ArrayList<String>();
+                xmlDeclared.add(sessionBean.getHome());
+                xmlDeclared.add(sessionBean.getRemote());
+                xmlDeclared.add(sessionBean.getLocalHome());
+                xmlDeclared.add(sessionBean.getLocal());
+
+                if (strict) { // when not being strict, thse
+                    xmlDeclared.addAll(sessionBean.getBusinessLocal());
+                    xmlDeclared.addAll(sessionBean.getBusinessRemote());
+                    xmlDeclared.add(sessionBean.getServiceEndpoint());
+                }
 
                 /*
                  * These interface types are not eligable to be business interfaces.
@@ -1334,11 +1342,13 @@
                     if (!name.equals("java.io.Serializable") &&
                             !name.equals("java.io.Externalizable") &&
                             !name.startsWith("javax.ejb.") &&
-                            !declared.contains(interfce.getName())) {
+                            !xmlDeclared.contains(interfce.getName())) {
                         interfaces.add(interfce);
                     }
                 }
 
+                List<Class> declared = new ArrayList<Class>();
+
                 /*
                  * @Remote
                  */
@@ -1348,24 +1358,26 @@
                     if (remote.value().length == 0) {
                         if (interfaces.size() != 1) {
                             validation.fail(ejbName, "ann.remote.noAttributes", join(", ", interfaces));
-                        } else if (clazz.getAnnotation(Local.class) != null) {
+                        } else if (strict && clazz.getAnnotation(Local.class) != null) {
                             validation.fail(ejbName, "ann.remoteLocal.ambiguous", join(", ", interfaces));
-                        } else if (interfaces.get(0).getAnnotation(Local.class) != null) {
+                        } else if (strict && interfaces.get(0).getAnnotation(Local.class) != null) {
                             validation.fail(ejbName, "ann.remoteLocal.conflict", join(", ", interfaces));
                         } else {
                             if (validateRemoteInterface(interfaces.get(0), validation, ejbName)) {
                                 remotes.add(interfaces.get(0));
                             }
-                            interfaces.remove(0);
+                            declared.add(interfaces.get(0));
                         }
                     } else for (Class interfce : remote.value()) {
                         if (validateRemoteInterface(interfce, validation, ejbName)) {
                             remotes.add(interfce);
                         }
-                        interfaces.remove(interfce);
+                        declared.add(interfce);
                     }
                 }
 
+                if (strict) interfaces.removeAll(declared);
+                
                 /*
                  * @Local
                  */
@@ -1375,24 +1387,26 @@
                     if (local.value().length == 0) {
                         if (interfaces.size() != 1) {
                             validation.fail(ejbName, "ann.local.noAttributes", join(", ", interfaces));
-                        } else if (clazz.getAnnotation(Remote.class) != null) {
+                        } else if (strict && clazz.getAnnotation(Remote.class) != null) {
                             validation.fail(ejbName, "ann.localRemote.ambiguous", join(", ", interfaces));
-                        } else if (interfaces.get(0).getAnnotation(Remote.class) != null) {
+                        } else if (strict && interfaces.get(0).getAnnotation(Remote.class) != null) {
                             validation.fail(ejbName, "ann.localRemote.conflict", join(", ", interfaces));
                         } else {
                             if (validateLocalInterface(interfaces.get(0), validation, ejbName)) {
                                 locals.add(interfaces.get(0));
                             }
-                            interfaces.remove(0);
+                            declared.add(interfaces.get(0));
                         }
                     } else for (Class interfce : local.value()) {
                         if (validateLocalInterface(interfce, validation, ejbName)) {
                             locals.add(interfce);
                         }
-                        interfaces.remove(interfce);
+                        declared.add(interfce);
                     }
                 }
 
+                if (strict) interfaces.removeAll(declared);
+
                 /*
                  * @WebService
                  * @WebServiceProvider
@@ -1405,7 +1419,7 @@
                             try {
                                 sessionBean.setServiceEndpoint(endpointInterfaceName);
                                 Class endpointInterface = Class.forName(endpointInterfaceName, false, ejbModule.getClassLoader());
-                                interfaces.remove(endpointInterface);
+                                declared.add(endpointInterface);
                             } catch (ClassNotFoundException e) {
                                 throw new IllegalStateException("Class not found @WebService.endpointInterface: " + endpointInterfaceName, e);
                             }
@@ -1417,27 +1431,49 @@
                     }
                 }
 
+                if (strict) interfaces.removeAll(declared);
+
                 /*
                  * The remainder of the interfaces are checked for annotations in this order:
                  * 1. @WebService
                  * 2. @Remote
                  * 3. Else assumed to be @Local
                  */
-                for (Class interfce : copy(interfaces)) {
+                for (Class interfce : interfaces) {
                     if (interfce.isAnnotationPresent(WebService.class)) {
-                        if (sessionBean.getServiceEndpoint().equals(DeploymentInfo.ServiceEndpoint.class.getName())) {
+                        if (sessionBean.getServiceEndpoint() == null){
+                            sessionBean.setServiceEndpoint(interfce.getName());
+                        } else if (sessionBean.getServiceEndpoint().equals(DeploymentInfo.ServiceEndpoint.class.getName())) {
                             sessionBean.setServiceEndpoint(interfce.getName());
                         }
-                        interfaces.remove(interfce);
-                    } else if (interfce.isAnnotationPresent(Remote.class)) {
+                        declared.add(interfce);
+                    }
+                }
+
+                if (strict) interfaces.removeAll(declared);
+
+                for (Class interfce : interfaces) {
+                    if (interfce.isAnnotationPresent(Remote.class)) {
                         remotes.add(interfce);
-                        interfaces.remove(interfce);
-                    } else {
+                        declared.add(interfce);
+                    }
+                }
+
+                if (strict) interfaces.removeAll(declared);
+
+                for (Class interfce : interfaces) {
+                    if (interfce.isAnnotationPresent(Local.class)) {
                         locals.add(interfce);
-                        interfaces.remove(interfce);
+                        declared.add(interfce);
                     }
                 }
 
+                if (!strict){
+                    // Treat the rest of the unannotated and undeclared interfaces implicitly as local interfaces
+                    interfaces.removeAll(declared);
+                    locals.addAll(interfaces);
+                }
+
                 /**
                  * The 'interfaces' list should now be empty and all interfaces
                  * of the bean sorted into either the remote or local bucket.
@@ -1452,6 +1488,15 @@
             }
         }
 
+        private String getProperty(EjbModule ejbModule, String key, String defaultValue) {
+            OpenejbJar openejbJar = ejbModule.getOpenejbJar();
+            String value = SystemInstance.get().getProperty(key, defaultValue);
+            if (openejbJar != null && openejbJar.getProperties() != null){
+                value = openejbJar.getProperties().getProperty(key, value);
+            }
+            return value;
+        }
+
         private void processSecurityAnnotations(Class<?> beanClass, String ejbName, EjbModule ejbModule, ClassFinder classFinder, EnterpriseBean bean) {
             AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationPrinter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationPrinter.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationPrinter.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationPrinter.java Thu Apr 16 03:12:08 2009
@@ -85,7 +85,7 @@
                     for (ListIterator<EjbReferenceInfo> iterator = jndiEnc.ejbReferences.listIterator(); iterator.hasNext();) {
                         EjbReferenceInfo ejbReference = iterator.next();
                         out(3, "--[" + iterator.previousIndex() + "]----------------------");
-                        out(3, "homeType        ", ejbReference.homeType);
+                        out(3, "homeType        ", ejbReference.homeClassName);
                         out(3, "referenceName   ", ejbReference.referenceName);
                         out(3, "ejbDeploymentId ", ejbReference.ejbDeploymentId);
                         if (ejbReference.location != null){

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java Thu Apr 16 03:12:08 2009
@@ -153,8 +153,8 @@
 
             EjbReferenceInfo info = new EjbReferenceInfo();
 
-            info.homeType = ref.getHome();
-            info.interfaceType = ref.getInterface();
+            info.homeClassName = ref.getHome();
+            info.interfaceClassName = ref.getInterface();
             info.referenceName = ref.getName();
             info.link = ref.getEjbLink();
             info.location = buildLocationInfo(ref);
@@ -221,8 +221,8 @@
         EjbLocalReferenceInfo l = new EjbLocalReferenceInfo();
         l.ejbDeploymentId = r.ejbDeploymentId;
         l.externalReference = r.externalReference;
-        l.homeType = r.homeType;
-        l.interfaceType = r.interfaceType;
+        l.homeClassName = r.homeClassName;
+        l.interfaceClassName = r.interfaceClassName;
         l.referenceName = r.referenceName;
         l.link = r.link;
         l.location = r.location;

Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/InheritenceTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/InheritenceTest.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/InheritenceTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/InheritenceTest.java Thu Apr 16 03:12:08 2009
@@ -379,8 +379,8 @@
         if (a == null || b == null) return false;
 
         if (a.referenceName != null ? !a.referenceName.equals(b.referenceName) : b.referenceName != null) return false;
-        if (a.homeType != null ? !a.homeType.equals(b.homeType) : b.homeType != null) return false;
-        if (a.interfaceType != null ? !a.interfaceType.equals(b.interfaceType) : b.interfaceType != null) return false;
+        if (a.homeClassName != null ? !a.homeClassName.equals(b.homeClassName) : b.homeClassName != null) return false;
+        if (a.interfaceClassName != null ? !a.interfaceClassName.equals(b.interfaceClassName) : b.interfaceClassName != null) return false;
         if (a.ejbDeploymentId != null ? !a.ejbDeploymentId.equals(b.ejbDeploymentId) : b.ejbDeploymentId != null)
             return false;
         if (a.link != null ? !a.link.equals(b.link) : b.link != null) return false;

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/MappedNameTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/MappedNameTest.java?rev=765456&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/MappedNameTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/MappedNameTest.java Thu Apr 16 03:12:08 2009
@@ -0,0 +1,86 @@
+/**
+ * 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.config;
+
+import junit.framework.TestCase;
+import org.apache.openejb.client.LocalInitialContextFactory;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.jee.oejb3.EjbDeployment;
+
+import javax.ejb.EJB;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MappedNameTest extends TestCase {
+
+    public void test() throws Exception {
+        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+
+        ConfigurationFactory config = new ConfigurationFactory();
+        Assembler assembler = new Assembler();
+
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        EjbJar ejbJar = new EjbJar();
+        ejbJar.addEnterpriseBean(new StatelessBean(GreenBean.class));
+        ejbJar.addEnterpriseBean(new StatelessBean(RedBean.class));
+
+        EjbModule ejbModule = new EjbModule(ejbJar, new OpenejbJar());
+
+        ejbModule.getOpenejbJar().addEjbDeployment(new EjbDeployment(null, "foo/bar/baz/Green", "GreenBean"));
+        ejbModule.getOpenejbJar().addEjbDeployment(new EjbDeployment(null, "foo/bar/baz/Red", "RedBean"));
+
+        EjbJarInfo info = config.configureApplication(ejbModule);
+        assembler.createApplication(info);
+
+        InitialContext initialContext = new InitialContext();
+        Color green = (Color) initialContext.lookup("foo/bar/baz/GreenLocal");
+        Color red = (Color) initialContext.lookup("foo/bar/baz/RedLocal");
+
+        red.test();
+    }
+
+    public static interface Color {
+
+        public void test() throws NamingException;
+
+    }
+
+    public static class GreenBean implements Color {
+        public void test() throws NamingException {
+        }
+    }
+
+    @EJB(name = "green", beanName = "GreenBean", beanInterface = Color.class)
+    public static class RedBean implements Color {
+
+        public void test() throws NamingException {
+            InitialContext initialContext = new InitialContext();
+            initialContext.lookup("java:comp/env/green");
+        }
+    }
+}

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/UberInterfaceTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/UberInterfaceTest.java?rev=765456&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/UberInterfaceTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/UberInterfaceTest.java Thu Apr 16 03:12:08 2009
@@ -0,0 +1,126 @@
+/**
+ * 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.config;
+
+import junit.framework.TestCase;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.DeploymentInfo;
+import org.apache.openejb.client.LocalInitialContextFactory;
+
+import javax.ejb.Local;
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+import javax.jws.WebService;
+import javax.naming.InitialContext;
+import static java.util.Arrays.asList;
+import java.io.Serializable;
+
+public class UberInterfaceTest extends TestCase {
+
+    public void test() throws Exception {}
+    
+    public void _test() throws Exception {
+        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+
+        ConfigurationFactory config = new ConfigurationFactory();
+        Assembler assembler = new Assembler();
+
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        EjbJar ejbJar = new EjbJar();
+        StatelessBean bean = ejbJar.addEnterpriseBean(new StatelessBean(SuperBean.class));
+
+        EjbJarInfo ejbJarInfo = config.configureApplication(ejbJar);
+
+        EnterpriseBeanInfo beanInfo = ejbJarInfo.enterpriseBeans.get(0);
+
+        assertEquals(asList(Everything.class.getName()), beanInfo.businessLocal);
+        assertEquals(asList(Everything.class.getName()), beanInfo.businessRemote);
+        assertEquals(Everything.class.getName(), beanInfo.serviceEndpoint);
+
+        assembler.createApplication(ejbJarInfo);
+
+        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
+        DeploymentInfo deployment = containerSystem.getDeploymentInfo(beanInfo.ejbDeploymentId);
+
+        assertEquals(asList(Everything.class), deployment.getBusinessLocalInterfaces());
+        assertEquals(asList(Everything.class), deployment.getBusinessRemoteInterfaces());
+        assertEquals(Everything.class, deployment.getServiceEndpointInterface());
+
+        InitialContext context = new InitialContext();
+
+        Everything local = (Everything) context.lookup("SuperBeanLocal");
+        Everything remote = (Everything) context.lookup("SuperBeanRemote");
+
+        Reference reference = new Reference("test");
+
+        assertEquals(reference, local.echo(reference));
+        assertSame(reference, local.echo(reference)); // pass by reference
+
+        assertEquals(reference, remote.echo(reference));
+        assertNotSame(reference, remote.echo(reference)); // pass by value
+    }
+
+
+    @Local
+    @Remote
+    @WebService
+    public static interface Everything {
+        public Object echo(Object o);
+    }
+
+    public static class SuperBean implements Everything {
+        public Object echo(Object o) {
+            return o;
+        }
+    }
+
+    public static class Reference implements Serializable {
+        private final String value;
+
+        public Reference(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Reference value1 = (Reference) o;
+
+            if (!value.equals(value1.value)) return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return value.hashCode();
+        }
+    }
+
+}

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/EJB.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/EJB.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/EJB.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/EJB.java Thu Apr 16 03:12:08 2009
@@ -18,6 +18,7 @@
 package org.apache.openejb.spring;
 
 import org.apache.openejb.DeploymentInfo;
+import org.apache.openejb.assembler.classic.JndiBuilder;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
 import org.springframework.beans.factory.FactoryBean;
@@ -83,7 +84,7 @@
         }
 
         // this is the pattern for the internal jndi name
-        String jndiName = "java:openejb/Deployment/" + deploymentInfo.getDeploymentID() + "/" + getInterface().getName();
+        String jndiName = "java:openejb/Deployment/" + JndiBuilder.format(deploymentInfo.getDeploymentID(), getInterface().getName());
 
         // perform the lookup against the jndi context in the container system
         ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);

Modified: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java?rev=765456&r1=765455&r2=765456&view=diff
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java (original)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java Thu Apr 16 03:12:08 2009
@@ -20,10 +20,8 @@
 import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.List;
 
 import org.apache.openejb.DeploymentInfo;
-import org.apache.openejb.OpenEJB;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.loader.SystemInstance;
@@ -191,11 +189,11 @@
         }
 
         for (EjbLocalReferenceInfo info : enc.ejbLocalReferences) {
-            printRow(info.referenceName, info.ejbDeploymentId, info.homeType, body);
+            printRow(info.referenceName, info.ejbDeploymentId, info.homeClassName, body);
         }
 
         for (EjbReferenceInfo info : enc.ejbReferences) {
-            printRow(info.referenceName, info.ejbDeploymentId, info.homeType, body);
+            printRow(info.referenceName, info.ejbDeploymentId, info.homeClassName, body);
         }
 
         for (ResourceReferenceInfo info : enc.resourceRefs) {