You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2008/08/16 08:22:44 UTC

svn commit: r686455 - in /openejb/trunk/openejb3/container: openejb-core/src/main/java/org/apache/openejb/assembler/classic/ openejb-spring/src/main/java/org/apache/openejb/spring/ openejb-spring/src/test/java/org/apache/openejb/spring/ openejb-spring/...

Author: dain
Date: Fri Aug 15 23:22:43 2008
New Revision: 686455

URL: http://svn.apache.org/viewvc?rev=686455&view=rev
Log:
Added support for auto export of EJBs to spring context
Redesigned bootstrap and configuratio of OpenEJB in Spring

Added:
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/AbstractApplication.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/ClassPathApplication.java
      - copied, changed from r686050, openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java
    openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/BasicSpringTest.java
      - copied, changed from r686050, openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java
    openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/LinkedBean.java
    openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/test.xml
      - copied, changed from r686050, openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml
Removed:
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringAssembler.java
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/BmpContainer.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/CmpContainer.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/EJB.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/MdbContainer.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJB.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJBResource.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Resource.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SingletonContainer.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatefulContainer.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatelessContainer.java
    openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java
    openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml

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=686455&r1=686454&r2=686455&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 Fri Aug 15 23:22:43 2008
@@ -79,7 +79,7 @@
         }
     }
 
-    private JndiNameStrategy createStrategy(EjbJarInfo ejbJar, HashMap<String, DeploymentInfo> deployments) {
+    public static JndiNameStrategy createStrategy(EjbJarInfo ejbJar, Map<String, DeploymentInfo> deployments) {
         String strategyClassName = SystemInstance.get().getProperty(JNDINAME_STRATEGY_CLASS, TemplatedStrategy.class.getName());
         strategyClassName = ejbJar.properties.getProperty(JNDINAME_STRATEGY_CLASS, strategyClassName);
 

Added: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/AbstractApplication.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/AbstractApplication.java?rev=686455&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/AbstractApplication.java (added)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/AbstractApplication.java Fri Aug 15 23:22:43 2008
@@ -0,0 +1,221 @@
+/**
+ *
+ * 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.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Map.Entry;
+import javax.annotation.PreDestroy;
+import javax.annotation.PostConstruct;
+
+import org.apache.openejb.DeploymentInfo;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.core.CoreDeploymentInfo;
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
+import org.apache.openejb.assembler.classic.JndiBuilder;
+import org.apache.openejb.assembler.classic.JndiBuilder.JndiNameStrategy;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public abstract class AbstractApplication implements ApplicationContextAware {
+    private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, ClassPathApplication.class);
+    private final Map<String, JndiNameStrategy> nameStrategies = new TreeMap<String, JndiNameStrategy>();
+
+    protected final List<AppInfo> applications = new ArrayList<AppInfo>();
+    protected OpenEJB openEJB;
+    protected boolean started = false;
+    protected boolean export = true;
+    private ConfigurableApplicationContext applicationContext;
+
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
+    }
+
+    public OpenEJB getOpenEJB() {
+        return openEJB;
+    }
+
+    public void setOpenEJB(OpenEJB openEJB) {
+        this.openEJB = openEJB;
+    }
+
+    public boolean isExport() {
+        return export;
+    }
+
+    public void setExport(boolean export) {
+        this.export = export;
+    }
+
+    protected abstract List<AppInfo> loadApplications() throws OpenEJBException;
+
+    @PostConstruct
+    public void start() throws OpenEJBException {
+        // check if openejb already started
+        if (openEJB == null) {
+            Map map = applicationContext.getBeansOfType(OpenEJB.class);
+            if (!map.isEmpty()) {
+                openEJB = (OpenEJB) map.values().iterator().next();
+            }
+        }
+        if (openEJB == null) {
+            openEJB = new OpenEJB();
+            applicationContext.getBeanFactory().registerSingleton("openejb.internalOpenEJB", openEJB);
+            openEJB.setApplicationContext(applicationContext);
+            openEJB.start();
+        }
+        openEJB.deployApplication(this);
+    }
+
+    // Do not make this the Spring start method
+    protected void deployApplication() throws OpenEJBException {
+        // Ok someone made this the OpenEJB start method... ignore this deploy call
+        if (openEJB != null && openEJB.isStarting()) return;
+
+        if (started) return;
+        started = true;
+
+        // load the applications
+        List<AppInfo> appInfos = loadApplications();
+
+        // deploy the applications
+        Assembler assembler = getAssembler();
+        for (AppInfo appInfo : appInfos) {
+            try {
+                List<DeploymentInfo> deployments = assembler.createApplication(appInfo, assembler.createAppClassLoader(appInfo), true);
+                if (export) {
+                    for (DeploymentInfo deployment : deployments) {
+                        JndiNameStrategy strategy = createStrategy(appInfo, deployments, deployment);
+                        Map<String, EJB> bindings = getEjbBindings(strategy, (CoreDeploymentInfo) deployment);
+                        for (Entry<String, EJB> entry : bindings.entrySet()) {
+                            String beanName = entry.getKey();
+                            if (!applicationContext.containsBean(beanName)) {
+                                EJB ejb = entry.getValue();
+                                applicationContext.getBeanFactory().registerSingleton(beanName, ejb);
+                                logger.info("Exported EJB " + deployment.getEjbName() + " with interface " + entry.getValue().getInterface().getName() + " to Spring bean " + entry.getKey());
+                            }
+                        }
+                    }
+                }
+                applications.add(appInfo);
+            } catch (Exception e) {
+                if (e instanceof OpenEJBException) {
+                    throw (OpenEJBException) e;
+                }
+                throw new OpenEJBException("Error starting application " + appInfo.jarPath, e);
+            }
+        }
+    }
+
+    public Map<String, EJB> getEjbBindings(JndiNameStrategy strategy, CoreDeploymentInfo deployment) {
+        strategy.begin(deployment);
+
+        Map<String, EJB> bindings = new TreeMap<String, EJB>();
+
+        Class remoteHome = deployment.getHomeInterface();
+        if (remoteHome != null) {
+            String externalName = strategy.getName(remoteHome, JndiNameStrategy.Interface.REMOTE_HOME);
+            bindings.put(externalName, new EJB(deployment, remoteHome));
+        }
+
+
+        Class localHome = deployment.getLocalHomeInterface();
+        if (localHome != null) {
+            String externalName = strategy.getName(localHome, JndiNameStrategy.Interface.LOCAL_HOME);
+            bindings.put(externalName, new EJB(deployment, remoteHome));
+        }
+
+        for (Class businessLocal : deployment.getBusinessLocalInterfaces()) {
+            String externalName = strategy.getName(businessLocal, JndiNameStrategy.Interface.BUSINESS_LOCAL);
+            bindings.put(externalName, new EJB(deployment, businessLocal));
+        }
+
+        for (Class businessRemote : deployment.getBusinessRemoteInterfaces()) {
+            String externalName = strategy.getName(businessRemote, JndiNameStrategy.Interface.BUSINESS_REMOTE);
+            bindings.put(externalName, new EJB(deployment, businessRemote));
+        }
+
+//        if (MessageListener.class.equals(deployment.getMdbInterface())) {
+//            String name = deployment.getDeploymentID().toString();
+//            bindings.put(name, MessageListener.class);
+//        }
+
+        strategy.end();
+
+        return bindings;
+    }
+
+    public JndiNameStrategy createStrategy(AppInfo appInfo, List<DeploymentInfo> deployments, DeploymentInfo deployment) throws OpenEJBException {
+        JndiNameStrategy strategy = nameStrategies.get(deployment.getModuleID());
+        if (strategy != null) {
+            return strategy;
+        }
+
+        String deploymentId = (String) deployment.getDeploymentID();
+        for (EjbJarInfo ejbJar : appInfo.ejbJars) {
+            if (ejbJar.moduleId.equals(deployment.getModuleID())) {
+                Set<String> moduleDeploymentIds = new TreeSet<String>();
+                for (EnterpriseBeanInfo enterpriseBean : ejbJar.enterpriseBeans) {
+                    moduleDeploymentIds.add(enterpriseBean.ejbDeploymentId);
+                }
+                Map<String, DeploymentInfo> moduleDeployments = new TreeMap<String, DeploymentInfo>();
+                for (DeploymentInfo deploymentInfo : deployments) {
+                    if (moduleDeploymentIds.contains(deploymentId)) {
+                        moduleDeployments.put((String) deploymentInfo.getDeploymentID(), deploymentInfo);
+                    }
+                }
+                strategy = JndiBuilder.createStrategy(ejbJar, moduleDeployments);
+                for (String moduleDeploymentId : moduleDeploymentIds) {
+                    nameStrategies.put(moduleDeploymentId, strategy);
+                }
+                return strategy;
+            }
+        }
+        throw new OpenEJBException("Can not find EjbJarInfo " + deployment.getModuleID() + " for EJB " + deploymentId);
+    }
+
+    @PreDestroy
+    public void stop() {
+        if (!started) return;
+        started = false;
+
+        for (AppInfo application : applications) {
+            try {
+                getAssembler().destroyApplication(application.jarPath);
+            } catch (Exception e) {
+                logger.error("Error stopping application " + application.jarPath, e);
+            }
+        }
+    }
+
+    protected Assembler getAssembler() {
+            return SystemInstance.get().getComponent(Assembler.class);
+    }
+}

Added: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java?rev=686455&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java (added)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java Fri Aug 15 23:22:43 2008
@@ -0,0 +1,53 @@
+/**
+ *
+ * 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.spring;
+
+import java.util.List;
+import java.util.Collections;
+import java.io.IOException;
+import java.io.File;
+
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.springframework.core.io.Resource;
+
+@Exported
+public class Application extends AbstractApplication {
+    private final ConfigurationFactory configurationFactory = new ConfigurationFactory();
+    private Resource jarFile;
+
+    public Resource getJarFile() {
+        return jarFile;
+    }
+
+    public void setJarFile(Resource jarFile) {
+        this.jarFile = jarFile;
+    }
+
+    protected List<AppInfo> loadApplications() throws OpenEJBException {
+        File file;
+        try {
+            file = jarFile.getFile();
+        } catch (IOException e) {
+            throw new OpenEJBException("Can not load application " + jarFile);
+        }
+        AppInfo appInfo = configurationFactory.configureApplication(file);
+        return Collections.singletonList(appInfo);
+    }
+}

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/BmpContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/BmpContainer.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/BmpContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/BmpContainer.java Fri Aug 15 23:22:43 2008
@@ -21,6 +21,7 @@
 
 import org.apache.openejb.config.BeanTypes;
 
+@Exported
 public class BmpContainer extends AbstractContainerProvider {
     private Integer poolSize;
 

Copied: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/ClassPathApplication.java (from r686050, openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java)
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/ClassPathApplication.java?p2=openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/ClassPathApplication.java&p1=openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java&r1=686050&r2=686455&rev=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Application.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/ClassPathApplication.java Fri Aug 15 23:22:43 2008
@@ -20,19 +20,12 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
-import javax.annotation.PreDestroy;
-import javax.annotation.PostConstruct;
 
-import org.apache.openejb.Container;
-import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.assembler.classic.AppInfo;
-import org.apache.openejb.assembler.classic.Assembler;
 import org.apache.openejb.assembler.classic.ClientInfo;
 import org.apache.openejb.assembler.classic.ConnectorInfo;
 import org.apache.openejb.assembler.classic.EjbJarInfo;
@@ -40,29 +33,11 @@
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.config.DeploymentsResolver;
 import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.spi.ContainerSystem;
-import org.apache.openejb.util.LogCategory;
-import org.apache.openejb.util.Logger;
-import org.springframework.beans.factory.annotation.Required;
 
 @Exported
-public class Application {
-    private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, Application.class);
+public class ClassPathApplication extends AbstractApplication {
     private final ConfigurationFactory configurationFactory = new ConfigurationFactory();
-    private final List<AppInfo> applications = new ArrayList<AppInfo>();
-    private final Map<Object, DeploymentInfo> notDeployed = new LinkedHashMap<Object, DeploymentInfo>();
-
-    private OpenEJB openEJB;
     private boolean classpathAsEar = true;
-    private boolean started = false;
-
-    public OpenEJB getOpenEJB() {
-        return openEJB;
-    }
-
-    public void setOpenEJB(OpenEJB openEJB) {
-        this.openEJB = openEJB;
-    }
 
     public boolean isClasspathAsEar() {
         return classpathAsEar;
@@ -72,14 +47,7 @@
         this.classpathAsEar = classpathAsEar;
     }
 
-    // Do not make this the Spring start method
-    public void deployApplication() throws OpenEJBException {
-        // Ok someone made this the OpenEJB start method... ignore this deploy call
-        if (openEJB != null && openEJB.isStarting()) return;
-
-        if (started) return;
-        started = true;
-
+    protected List<AppInfo> loadApplications() throws OpenEJBException {
         Set<String> declaredApplications = getDeployedApplications();
 
         List<String> classpathApps = new ArrayList<String>();
@@ -96,75 +64,17 @@
             jarFiles.add(new File(path));
         }
 
-        Assembler assembler = getAssembler();
+        List<AppInfo> appInfos = new ArrayList<AppInfo>();
         if (classpathAsEar) {
             AppInfo appInfo = configurationFactory.configureApplication(classLoader, "classpath.ear", jarFiles);
-            deployApplication(assembler, appInfo);
+            appInfos.add(appInfo);
         } else {
             for (File jarFile : jarFiles) {
                 AppInfo appInfo = configurationFactory.configureApplication(jarFile);
-                deployApplication(assembler, appInfo);
-            }
-        }
-    }
-
-    private void deployApplication(Assembler assembler, AppInfo appInfo) throws OpenEJBException {
-        try {
-            List<DeploymentInfo> deployments = assembler.createApplication(appInfo, assembler.createAppClassLoader(appInfo), false);
-            for (DeploymentInfo deployment : deployments) {
-                this.notDeployed.put(deployment.getDeploymentID(), deployment);
-            }
-            applications.add(appInfo);
-        } catch (Exception e) {
-            if (e instanceof OpenEJBException) {
-                throw (OpenEJBException) e;
-            }
-            throw new OpenEJBException("Error starting application " + appInfo.jarPath, e);
-        }
-    }
-
-    @PreDestroy
-    public void stop() {
-        if (!started) return;
-        started = false;
-
-        for (AppInfo application : applications) {
-            try {
-                getAssembler().destroyApplication(application.jarPath);
-            } catch (Exception e) {
-                logger.error("Error stopping application " + application.jarPath, e);
+                appInfos.add(appInfo);
             }
         }
-    }
-
-    public void startEjb(Object deploymentId) throws OpenEJBException {
-        if (deploymentId == null) throw new NullPointerException("deploymentId is null");
-
-        deployApplication();
-
-        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
-        DeploymentInfo deployment = containerSystem.getDeploymentInfo(deploymentId);
-        if (deployment == null) {
-            throw new IllegalArgumentException("Unknwon EJB " + deployment);
-        }
-
-        deployment = notDeployed.remove(deploymentId);
-        if (deployment == null) {
-            // already deployed
-            return;
-        }
-
-        Container container = deployment.getContainer();
-        container.deploy(deployment);
-        logger.info("createApplication.createdEjb", deployment.getDeploymentID(), deployment.getEjbName(), container.getContainerID());
-    }
-
-    private Assembler getAssembler() {
-        if (openEJB != null) {
-            return openEJB.getAssembler();
-        } else {
-            return SystemInstance.get().getComponent(Assembler.class);
-        }
+        return appInfos;
     }
 
     private Set<String> getDeployedApplications() {

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/CmpContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/CmpContainer.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/CmpContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/CmpContainer.java Fri Aug 15 23:22:43 2008
@@ -21,6 +21,7 @@
 
 import org.apache.openejb.config.BeanTypes;
 
+@Exported
 public class CmpContainer extends AbstractContainerProvider {
     private String cmpEngineFactory;
 

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=686455&r1=686454&r2=686455&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 Fri Aug 15 23:22:43 2008
@@ -17,10 +17,7 @@
  */
 package org.apache.openejb.spring;
 
-import javax.annotation.PostConstruct;
-
 import org.apache.openejb.DeploymentInfo;
-import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
 import org.springframework.beans.factory.FactoryBean;
@@ -28,28 +25,46 @@
 
 @Exported
 public class EJB<T> implements FactoryBean {
-    private Application application;
     private Object deploymentId;
+    private DeploymentInfo deploymentInfo;
     private Class<T> intf;
 
-    public Application getApplication() {
-        return application;
+    public EJB() {
     }
 
-    @Required
-    public void setApplication(Application application) {
-        this.application = application;
+    public EJB(DeploymentInfo deploymentInfo, Class<T> intf) {
+        this.deploymentInfo = deploymentInfo;
+        this.intf = intf;
     }
 
     public Object getDeploymentId() {
-        return deploymentId;
+        if (deploymentId != null) {
+            return deploymentId;
+        } else if (deploymentInfo != null) {
+            return deploymentInfo.getDeploymentID();
+        }
+        return null;
     }
 
-    @Required
     public void setDeploymentId(Object deploymentId) {
         this.deploymentId = deploymentId;
     }
 
+    public DeploymentInfo getDeploymentInfo() {
+        if (deploymentInfo != null) {
+            return deploymentInfo;
+        } else if (deploymentId != null) {
+            ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
+            DeploymentInfo deploymentInfo = containerSystem.getDeploymentInfo(deploymentId);
+            return deploymentInfo;
+        }
+        return null;
+    }
+
+    public void setDeploymentInfo(DeploymentInfo deploymentInfo) {
+        this.deploymentInfo = deploymentInfo;
+    }
+
     public Class<T> getInterface() {
         return intf;
     }
@@ -59,29 +74,22 @@
         this.intf = intf;
     }
 
-    @PostConstruct
-    public void start() throws OpenEJBException {
-    }
-
     public T getObject() throws Exception {
-        if (application == null) throw new NullPointerException("application is null");
-        if (deploymentId == null) throw new NullPointerException("deploymentId is null");
         if (intf == null) throw new NullPointerException("intf is null");
 
-        application.startEjb(deploymentId);
-
-        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
-        DeploymentInfo deploymentInfo = containerSystem.getDeploymentInfo(deploymentId);
+        DeploymentInfo deploymentInfo = getDeploymentInfo();
         if (deploymentInfo == null) {
-            throw new IllegalArgumentException("Unknwon EJB " + deploymentInfo);
+            throw new IllegalStateException("DeploymentInfo or DeploymentID must be set before EJB can be retrieved");
         }
-        
-        String jndiName = "java:openejb/Deployment/" + deploymentId + "/" + getInterface().getName();
 
+        // this is the pattern for the internal jndi name
+        String jndiName = "java:openejb/Deployment/" + deploymentInfo.getDeploymentID() + "/" + getInterface().getName();
+
+        // perform the lookup against the jndi context in the container system
+        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
         Object proxy = containerSystem.getJNDIContext().lookup(jndiName);
         if (!intf.isInstance(proxy)) {
-            throw new IllegalArgumentException(
-                    "EJB at " + jndiName + " is not an instance of " + intf.getName() + ", but is " + proxy.getClass().getName());
+            throw new IllegalArgumentException("EJB at " + jndiName + " is not an instance of " + intf.getName() + ", but is " + proxy.getClass().getName());
         }
         return intf.cast(proxy);
     }

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/MdbContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/MdbContainer.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/MdbContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/MdbContainer.java Fri Aug 15 23:22:43 2008
@@ -21,6 +21,7 @@
 
 import org.apache.openejb.config.BeanTypes;
 
+@Exported
 public class MdbContainer extends AbstractContainerProvider {
     private String resourceAdapter;
     private String messageListenerInterface;

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJB.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJB.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJB.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJB.java Fri Aug 15 23:22:43 2008
@@ -17,10 +17,16 @@
  */
 package org.apache.openejb.spring;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Properties;
-import java.util.Collection;
-import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
 import javax.annotation.PostConstruct;
 import javax.naming.Context;
 import javax.naming.NamingException;
@@ -29,31 +35,35 @@
 import org.apache.openejb.Container;
 import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.OpenEJBException;
-import org.apache.openejb.core.ServerFederation;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ContainerInfo;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.ResourceInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.ServiceInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.dynamic.PassthroughFactory;
+import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.spi.ApplicationServer;
-import org.apache.openejb.spi.Assembler;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.Messages;
 import org.apache.openejb.util.OpenEjbVersion;
 import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 
 @Exported
-public class OpenEJB implements ApplicationContextAware{
+public class OpenEJB implements ApplicationContextAware {
     private static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, "org.apache.openejb.util.resources");
-    private static Messages messages = new Messages("org.apache.openejb.util.resources");
-
-    private final Properties properties = new Properties();
 
     /**
-     * The assembler for Spring embedded.
+     * Properties added to the OpenEJB SystemInstance on startup.
      */
-    private SpringAssembler assembler;
+    private final Properties properties = new Properties();
 
     /**
      * The TransactionManager to be used by the OpenEJB server, or null for the
@@ -68,24 +78,39 @@
     private SecurityService securityService;
 
     /**
-     * The ApplicationServer to be used by the OpenEJB server, or null for the
-     * default ApplicationServer.
+     * Containers to add to the OpenEJB server.
      */
-    private ApplicationServer applicationServer;
-
     private final Collection<ContainerProvider> containers = new ArrayList<ContainerProvider>();
 
+    /**
+     * Resources to add to the OpenEJB server.
+     */
     private final Collection<ResourceProvider> resources = new ArrayList<ResourceProvider>();
 
+    /**
+     * Should the beans in the Spring context be imported into OpenEJB as resources?
+     */
     private boolean importContext = true;
 
+    /**
+     * Is this bean starting?
+     */
     private boolean starting;
-    private Throwable initialized;
+
+    /**
+     * While OpenEJB is starting any applications that are deployed are queued up until startup is complete.
+     */
+    private final List<AbstractApplication> applicationsToDeploy = new ArrayList<AbstractApplication>();
+
+    /**
+     * The application context to scan when importing Beans.
+     */
     private ApplicationContext applicationContext;
 
-    public SpringAssembler getAssembler() {
-        return assembler;
-    }
+    /**
+     * The IDs of the resources we have already imported
+     */
+    private final Set<String> importedResourceIds = new TreeSet<String>();
 
     public ApplicationContext getApplicationContext() {
         return applicationContext;
@@ -120,14 +145,6 @@
         this.securityService = securityService;
     }
 
-    public ApplicationServer getApplicationServer() {
-        return applicationServer;
-    }
-
-    public void setApplicationServer(ApplicationServer applicationServer) {
-        this.applicationServer = applicationServer;
-    }
-
     public Collection<ContainerProvider> getContainers() {
         return containers;
     }
@@ -168,23 +185,18 @@
     }
 
     public boolean isStarted() {
-        return initialized != null || SystemInstance.get().getComponent(ContainerSystem.class) != null;
+        return SystemInstance.get().getComponent(ContainerSystem.class) != null;
     }
 
     @PostConstruct
     public void start() throws OpenEJBException {
-        //
-        // Already started?
-        //
+        // Transaction mananager and system instance can only be set once per SystemInstance (one per ClassLoader)
         if (isStarted()) {
-            if (initialized != null){
-                String msg = messages.message("startup.alreadyInitialized");
-                logger.error(msg, initialized);
-                throw new OpenEJBException(msg, initialized);
-            } else {
-                String msg = messages.message("startup.alreadyInitialized");
-                logger.error(msg);
-                throw new OpenEJBException(msg);
+            if (transactionManager != null) {
+                throw new OpenEJBException("TransactionManager can not be set because OpenEJB has already been initalized");
+            }
+            if (securityService != null) {
+                throw new OpenEJBException("SecurityService can not be set because OpenEJB has already been initalized");
             }
         }
 
@@ -199,12 +211,8 @@
         //
         // System Instance
         //
-        try {
-            SystemInstance.init(properties);
-        } catch (Exception e) {
-            throw new OpenEJBException(e);
-        }
         SystemInstance system = SystemInstance.get();
+        system.getProperties().putAll(properties);
 
         // do not deploy applications in claspath
         system.setProperty("openejb.deployments.classpath", "false");
@@ -212,90 +220,131 @@
         // we are in embedded mode
         system.setProperty("openejb.embedded", "true");
 
-
         //
-        // Startup message
+        // Add TransactionManager and SecurityService to OpenEJB
         //
-        OpenEjbVersion versionInfo = OpenEjbVersion.get();
+        ConfigurationFactory configurationFactory = new ConfigurationFactory();
+        Assembler assembler;
+        if (isStarted()) {
+            assembler = SystemInstance.get().getComponent(Assembler.class);
+        } else {
+            //
+            // Startup message
+            //
+            OpenEjbVersion versionInfo = OpenEjbVersion.get();
 
-        if (properties.getProperty("openejb.nobanner") == null) {
-            System.out.println("Apache OpenEJB " + versionInfo.getVersion() + "    build: " + versionInfo.getDate() + "-" + versionInfo.getTime());
-            System.out.println("" + versionInfo.getUrl());
-        }
+            if (properties.getProperty("openejb.nobanner") == null) {
+                System.out.println("Apache OpenEJB " + versionInfo.getVersion() + "    build: " + versionInfo.getDate() + "-" + versionInfo.getTime());
+                System.out.println("" + versionInfo.getUrl());
+            }
 
-        Logger logger2 = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
-        logger2.info("startup.banner", versionInfo.getUrl(), new Date(), versionInfo.getCopyright(),
-                versionInfo.getVersion(), versionInfo.getDate(), versionInfo.getTime());
+            Logger logger2 = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
+            logger2.info("startup.banner", versionInfo.getUrl(), new Date(), versionInfo.getCopyright(),
+                    versionInfo.getVersion(), versionInfo.getDate(), versionInfo.getTime());
 
-        logger.info("openejb.home = " + SystemInstance.get().getHome().getDirectory().getAbsolutePath());
-        logger.info("openejb.base = " + SystemInstance.get().getBase().getDirectory().getAbsolutePath());
+            logger.info("openejb.home = " + SystemInstance.get().getHome().getDirectory().getAbsolutePath());
+            logger.info("openejb.base = " + SystemInstance.get().getBase().getDirectory().getAbsolutePath());
 
-        Properties props = new Properties(SystemInstance.get().getProperties());
+            Properties props = new Properties(SystemInstance.get().getProperties());
 
-        if (properties.isEmpty()) {
-            logger.debug("startup.noInitializationProperties");
-        } else {
-            props.putAll(properties);
-        }
+            if (properties.isEmpty()) {
+                logger.debug("startup.noInitializationProperties");
+            } else {
+                props.putAll(properties);
+            }
 
-        //
-        // Application Server
-        //
-        if (applicationServer == null) {
-            applicationServer = new ServerFederation();
+            //
+            // Assembler
+            //
+            assembler = new Assembler();
+            assembler.createProxyFactory(configurationFactory.configureService(ProxyFactoryInfo.class));
+
+            //
+            // Transaction Manager
+            //
+            TransactionManager transactionManager = getTransactionManager();
+            if (transactionManager == null) {
+                transactionManager = getBeanForType(applicationContext, TransactionManager.class);
+            }
+            if (transactionManager != null) {
+                TransactionServiceInfo info = initPassthrough(new TransactionServiceInfo(), "TransactionManager", transactionManager);
+                assembler.createTransactionManager(info);
+            }
+
+            //
+            // Security Service
+            //
+            SecurityService securityService = getSecurityService();
+            if (securityService == null) {
+                securityService = getBeanForType(applicationContext, SecurityService.class);
+            }
+            if (securityService != null) {
+                SecurityServiceInfo info = initPassthrough(new SecurityServiceInfo(), "SecurityService", securityService);
+                assembler.createSecurityService(info);
+            }
         }
-        system.setComponent(ApplicationServer.class, applicationServer);
 
         //
-        // Assembler
+        // Resources
         //
-        assembler = new SpringAssembler(this);
-        SystemInstance.get().setComponent(Assembler.class, assembler);
-
-        try {
-            assembler.init(props);
-        } catch (OpenEJBException oe) {
-            logger.fatal("startup.assemblerFailedToInitialize", oe);
-            throw oe;
-        } catch (Throwable t) {
-            String msg = messages.message("startup.assemblerEncounteredUnexpectedError");
-            logger.fatal(msg, t);
-            throw new OpenEJBException(msg, t);
+        for (Object resourceProvider : applicationContext.getBeansOfType(ResourceProvider.class).values()) {
+            resources.add((ResourceProvider) resourceProvider);
         }
-
-        try {
-            assembler.build();
-        } catch (OpenEJBException oe) {
-            logger.fatal("startup.assemblerFailedToBuild", oe);
-            throw oe;
-        } catch (Throwable t) {
-            String msg = messages.message("startup.assemblerEncounterUnexpectedBuildError");
-            logger.fatal(msg, t);
-            throw new OpenEJBException(msg, t);
+        for (ResourceProvider resourceProvider : getResources()) {
+            ResourceInfo info = configurationFactory.configureService(resourceProvider.getResourceDefinition(), ResourceInfo.class);
+            importedResourceIds.add(info.id);
+            assembler.createResource(info);
+        }
+        if (isImportContext() && applicationContext != null) {
+            for (String beanName : applicationContext.getBeanDefinitionNames()) {
+                if (!importedResourceIds.contains(beanName)) {
+                    Class beanType = applicationContext.getType(beanName);
+                    Class factoryType = applicationContext.getType("&" + beanName);
+                    if (isImportableType(beanType, factoryType)) {
+                        SpringReference factory = new SpringReference(applicationContext, beanName, beanType);
+
+                        ResourceInfo info = initPassthrough(beanName, new ResourceInfo(), "Resource", factory);
+                        info.types = getTypes(beanType);
+                        assembler.createResource(info);
+                    }
+                }
+            }
         }
 
         //
-        // Container System
+        // Containers
         //
-        ContainerSystem containerSystem = assembler.getContainerSystem();
-        if (containerSystem == null) {
-            String msg = messages.message("startup.assemblerReturnedNullContainer");
-            logger.fatal(msg);
-            throw new OpenEJBException(msg);
+        for (Object containerProvider : applicationContext.getBeansOfType(ContainerProvider.class).values()) {
+            containers.add((ContainerProvider) containerProvider);
+        }
+        for (ContainerProvider containerProvider: getContainers()) {
+            ContainerInfo info = configurationFactory.createContainerInfo(containerProvider.getContainerDefinition());
+            assembler.createContainer(info);
         }
-        system.setComponent(ContainerSystem.class, containerSystem);
-        printContainerSystem(containerSystem);
-
 
         //
         // Done
         //
-        initialized = new Exception("Initialized at " + new Date()).fillInStackTrace();
         starting = false;
         logger.debug("startup.ready");
+
+        List<AbstractApplication> applicationsToDeploy = new ArrayList<AbstractApplication>(this.applicationsToDeploy);
+        this.applicationsToDeploy.clear();
+        for (AbstractApplication application : applicationsToDeploy) {
+            application.deployApplication();
+        }
+    }
+
+    public void deployApplication(AbstractApplication application) throws OpenEJBException {
+        if (isStarting() || !isStarted()) {
+            applicationsToDeploy.add(application);
+        } else {
+            application.deployApplication();
+        }
     }
 
-    private void printContainerSystem(ContainerSystem containerSystem) {
+    public void printContainerSystem() {
+        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
         if (logger.isDebugEnabled()) {
             //
             // Log Containers
@@ -362,7 +411,55 @@
         }
     }
 
-    public Throwable getInitialized() {
-        return initialized;
+    private <T> T getBeanForType(ApplicationContext applicationContext, Class<T> type) throws OpenEJBException {
+        String[] names = applicationContext.getBeanNamesForType(type);
+        if (names.length == 0) {
+            return null;
+        }
+        if (names.length > 1) {
+            throw new OpenEJBException("Multiple " + type.getSimpleName() + " beans in application context: " + Arrays.toString(names));
+        }
+
+        String name = names[0];
+        importedResourceIds.add(name);
+        return (T) applicationContext.getBean(name);
+    }
+
+    private boolean isImportableType(Class type, Class factoryType) {
+        return !type.isAnnotationPresent(Exported.class) &&
+                !BeanPostProcessor.class.isAssignableFrom(type) &&
+                !BeanFactoryPostProcessor.class.isAssignableFrom(type) &&
+                (factoryType == null || !factoryType.isAnnotationPresent(Exported.class));
+    }
+
+    private <T extends ServiceInfo> T initPassthrough(T info, String serviceType, Object instance) {
+        return initPassthrough("Spring SuppliedÊ" + serviceType, info, serviceType, instance);
+    }
+
+    private <T extends ServiceInfo> T initPassthrough(String id, T info, String serviceType, Object instance) {
+        info.id = id;
+        info.service = serviceType;
+        info.types = getTypes(instance);
+        PassthroughFactory.add(info, instance);
+        return info;
+    }
+
+    private List<String> getTypes(Object instance) {
+        LinkedHashSet<String> types = new LinkedHashSet<String>();
+        Class clazz = instance.getClass();
+        addTypes(clazz, types);
+        return new ArrayList<String>(types);
+    }
+
+    private void addTypes(Class clazz, LinkedHashSet<String> types) {
+        if (clazz == null || Object.class.equals(clazz) || Serializable.class.equals(clazz)) {
+            return;
+        }
+        if (types.add(clazz.getName())) {
+            addTypes(clazz.getSuperclass(), types);
+            for (Class intf : clazz.getInterfaces()) {
+                addTypes(intf, types);
+            }
+        }
     }
 }

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJBResource.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJBResource.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJBResource.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/OpenEJBResource.java Fri Aug 15 23:22:43 2008
@@ -23,6 +23,7 @@
 import org.apache.openejb.spi.ContainerSystem;
 import org.springframework.beans.factory.FactoryBean;
 
+@Exported
 public class OpenEJBResource<T> implements FactoryBean {
     private final Class<T> type;
     private String resourceId;

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Resource.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Resource.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Resource.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/Resource.java Fri Aug 15 23:22:43 2008
@@ -19,6 +19,7 @@
 
 import java.util.Properties;
 
+@Exported
 public class Resource extends AbstractResourceProvider {
     private String type;
     private final Properties properties = new Properties();

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SingletonContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SingletonContainer.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SingletonContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SingletonContainer.java Fri Aug 15 23:22:43 2008
@@ -24,6 +24,7 @@
 import org.apache.openejb.config.sys.Container;
 import org.springframework.beans.factory.BeanNameAware;
 
+@Exported
 public class SingletonContainer extends AbstractContainerProvider {
     private String accessTimeout;
 

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatefulContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatefulContainer.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatefulContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatefulContainer.java Fri Aug 15 23:22:43 2008
@@ -21,6 +21,7 @@
 
 import org.apache.openejb.config.BeanTypes;
 
+@Exported
 public class StatefulContainer extends AbstractContainerProvider {
     private String passivator;
     private Integer timeOut;

Modified: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatelessContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatelessContainer.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatelessContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/StatelessContainer.java Fri Aug 15 23:22:43 2008
@@ -21,6 +21,7 @@
 
 import org.apache.openejb.config.BeanTypes;
 
+@Exported
 public class StatelessContainer extends AbstractContainerProvider {
     private String passivator;
     private Integer timeOut;

Copied: openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/BasicSpringTest.java (from r686050, openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java)
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/BasicSpringTest.java?p2=openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/BasicSpringTest.java&p1=openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java&r1=686050&r2=686455&rev=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/BasicSpringTest.java Fri Aug 15 23:22:43 2008
@@ -17,108 +17,27 @@
  */
 package org.apache.openejb.spring;
 
-import javax.naming.Context;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
 import junit.framework.TestCase;
-import org.apache.commons.dbcp.BasicDataSource;
-import org.apache.openejb.Container;
-import org.apache.openejb.util.Debug;
-import org.apache.openejb.core.entity.EntityContainer;
-import org.apache.openejb.core.cmp.*;
-import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.spi.ContainerSystem;
-import org.apache.openejb.spi.SecurityService;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
-public class SpringTest extends TestCase {
+public class BasicSpringTest extends TestCase {
     public void test() throws Exception {
-        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("org/apache/openejb/spring/spring.xml");
+        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("org/apache/openejb/spring/test.xml");
         assertTrue(context.getBeanDefinitionCount() > 0);
 
-        //
-        // OpenEJB
-        //
-        OpenEJB openEJB = (OpenEJB) context.getBean("OpenEJB");
-        assertNotNull("openEJB is null", openEJB);
-        assertTrue(openEJB.isStarted());
-        assertTrue(org.apache.openejb.OpenEJB.isInitialized());
-        
-        //
-        // ContainerSystem
-        //
-        ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
-        assertNotNull("containerSystem is null", containerSystem);
-        Context initialContext = containerSystem.getJNDIContext();
-        assertNotNull(initialContext);
-
-        //
-        // TransactionManager
-        //
-        Object tm = context.getBean("tm");
-        TransactionManager springTM = (TransactionManager) tm;
-        assertNotNull("springTM is null", springTM);
-        assertTrue("springTM should be an instance of MockTransactionManager", springTM instanceof MockTransactionManager);
-
-        TransactionManager systemTM = SystemInstance.get().getComponent(TransactionManager.class);
-        assertNotNull("systemTM is null", systemTM);
-        assertSame(springTM, systemTM);
-
-        assertSame(springTM, initialContext.lookup("openejb/TransactionManager"));
-
-        //
-        // SecurityService
-        //
-        SecurityService springSecurityService = (SecurityService) context.getBean("sec");
-        assertNotNull("springSecurityService is null", springSecurityService);
-        assertTrue("springSecurityService should be an instance of MockSecurityService", springSecurityService instanceof MockSecurityService);
-
-        SecurityService systemSecurityService = SystemInstance.get().getComponent(SecurityService.class);
-        assertNotNull("systemSecurityService is null", systemSecurityService);
-        assertSame(springSecurityService, systemSecurityService);
-
-        assertSame(springSecurityService, initialContext.lookup("openejb/SecurityService"));
-
-        //
-        // DataSource
-        //
-        DataSource springDataSource = (DataSource) context.getBean("ds");
-        assertNotNull("springDataSource is null", springDataSource);
-        assertTrue("springDataSource should be an instance of BasicDataSource", springDataSource instanceof BasicDataSource);
-
-        DataSource jndiDataSource = (DataSource) initialContext.lookup("openejb/Resource/ds");
-        assertSame(springDataSource, jndiDataSource);
-
-        DataSource exportedDS = (DataSource) context.getBean("openejbDS");
-        assertSame(springDataSource, exportedDS);
-
-        //
-        // Container
-        //
-        Container singletonContainer = containerSystem.getContainer("Spring Defined SingletonContainer");
-        assertTrue("singletonContainer should be an instance of SingletonContainer", singletonContainer instanceof org.apache.openejb.core.singleton.SingletonContainer);
-        Container statelessContainer = containerSystem.getContainer("Spring Defined StatelessContainer");
-        assertTrue("statelessContainer should be an instance of StatelessContainer", statelessContainer instanceof org.apache.openejb.core.stateless.StatelessContainer);
-        Container statefulContainer = containerSystem.getContainer("Spring Defined StatefulContainer");
-        assertTrue("statefulContainer should be an instance of StatefulContainer", statefulContainer instanceof org.apache.openejb.core.stateful.StatefulContainer);
-        Container mdbContainer = containerSystem.getContainer("Spring Defined MdbContainer");
-        assertTrue("mdbContainer should be an instance of MdbContainer", mdbContainer instanceof org.apache.openejb.core.mdb.MdbContainer);
-        Container bmpContainer = containerSystem.getContainer("Spring Defined BmpContainer");
-        assertTrue("bmpContainer should be an instance of BmpContainer", bmpContainer instanceof EntityContainer);
-        Container cmpContainer = containerSystem.getContainer("Spring Defined CmpContainer");
-        assertTrue("cmpContainer should be an instance of CmpContainer", cmpContainer instanceof org.apache.openejb.core.cmp.CmpContainer);
-
-        //
-        // EJB
-        //
-        Echo echo = (Echo) context.getBean("EchoBean");
-        assertNotNull("echo is null", echo);
-        assertEquals("olleH", echo.echo("Hello"));
-
-        System.out.println();
-        System.out.println();
-        Debug.printContext(initialContext);
+        LinkedBean next = (LinkedBean) context.getBean("next");
+        assertNotNull("next is null", next);
+        LinkedBean first = (LinkedBean) context.getBean("first");
+        assertNotNull("first is null", first);
+
+        assertEquals(next, first.getNext());
+
+        LinkedBean nextBean = (LinkedBean) context.getBean("nextBean");
+        assertNotNull("nextBean is null", nextBean);
+        assertSame(next, nextBean);
+        LinkedBean firstBean = (LinkedBean) context.getBean("firstBean");
+        assertNotNull("first is null", firstBean);
+        assertSame(first, firstBean);
 
 
         //
@@ -126,4 +45,4 @@
         //
         context.destroy();
     }
-}
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/LinkedBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/LinkedBean.java?rev=686455&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/LinkedBean.java (added)
+++ openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/LinkedBean.java Fri Aug 15 23:22:43 2008
@@ -0,0 +1,74 @@
+/**
+ *
+ * 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.spring;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class LinkedBean implements ApplicationContextAware, BeanNameAware {
+    private LinkedBean next;
+    private ConfigurableApplicationContext applicationContext;
+    private String name;
+
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = (ConfigurableApplicationContext) applicationContext;
+    }
+
+    public void setBeanName(String name) {
+        this.name = name;
+    }
+
+    @PostConstruct
+    public void start() {
+        applicationContext.getBeanFactory().registerSingleton(name + "Bean", new TestFactoryBean(this));
+    }
+
+    public LinkedBean getNext() {
+        return next;
+    }
+
+    public void setNext(LinkedBean next) {
+        this.next = next;
+    }
+
+    private static class TestFactoryBean implements FactoryBean {
+        private final LinkedBean bean;
+
+        private TestFactoryBean(LinkedBean bean) {
+            this.bean = bean;
+        }
+
+        public Object getObject() {
+            return bean;
+        }
+
+        public Class getObjectType() {
+            return LinkedBean.class;
+        }
+
+        public boolean isSingleton() {
+            return true;
+        }
+    }
+}

Modified: openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/test/java/org/apache/openejb/spring/SpringTest.java Fri Aug 15 23:22:43 2008
@@ -17,6 +17,7 @@
  */
 package org.apache.openejb.spring;
 
+import java.util.Map;
 import javax.naming.Context;
 import javax.sql.DataSource;
 import javax.transaction.TransactionManager;
@@ -24,12 +25,11 @@
 import junit.framework.TestCase;
 import org.apache.commons.dbcp.BasicDataSource;
 import org.apache.openejb.Container;
-import org.apache.openejb.util.Debug;
 import org.apache.openejb.core.entity.EntityContainer;
-import org.apache.openejb.core.cmp.*;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.spi.SecurityService;
+import org.apache.openejb.util.Debug;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
 public class SpringTest extends TestCase {
@@ -40,11 +40,13 @@
         //
         // OpenEJB
         //
-        OpenEJB openEJB = (OpenEJB) context.getBean("OpenEJB");
+        Map map = context.getBeansOfType(OpenEJB.class);
+        assertEquals("OpenEJB instance count", 1, map.size());
+        OpenEJB openEJB = (OpenEJB) map.values().iterator().next();
         assertNotNull("openEJB is null", openEJB);
         assertTrue(openEJB.isStarted());
         assertTrue(org.apache.openejb.OpenEJB.isInitialized());
-        
+
         //
         // ContainerSystem
         //
@@ -96,30 +98,37 @@
         //
         // Container
         //
-        Container singletonContainer = containerSystem.getContainer("Spring Defined SingletonContainer");
+        Container singletonContainer = containerSystem.getContainer("SpringDefinedSingletonContainer");
         assertTrue("singletonContainer should be an instance of SingletonContainer", singletonContainer instanceof org.apache.openejb.core.singleton.SingletonContainer);
-        Container statelessContainer = containerSystem.getContainer("Spring Defined StatelessContainer");
+        Container statelessContainer = containerSystem.getContainer("SpringDefinedStatelessContainer");
         assertTrue("statelessContainer should be an instance of StatelessContainer", statelessContainer instanceof org.apache.openejb.core.stateless.StatelessContainer);
-        Container statefulContainer = containerSystem.getContainer("Spring Defined StatefulContainer");
+        Container statefulContainer = containerSystem.getContainer("SpringDefinedStatefulContainer");
         assertTrue("statefulContainer should be an instance of StatefulContainer", statefulContainer instanceof org.apache.openejb.core.stateful.StatefulContainer);
-        Container mdbContainer = containerSystem.getContainer("Spring Defined MdbContainer");
+        Container mdbContainer = containerSystem.getContainer("SpringDefinedMdbContainer");
         assertTrue("mdbContainer should be an instance of MdbContainer", mdbContainer instanceof org.apache.openejb.core.mdb.MdbContainer);
-        Container bmpContainer = containerSystem.getContainer("Spring Defined BmpContainer");
+        Container bmpContainer = containerSystem.getContainer("SpringDefinedBmpContainer");
         assertTrue("bmpContainer should be an instance of BmpContainer", bmpContainer instanceof EntityContainer);
-        Container cmpContainer = containerSystem.getContainer("Spring Defined CmpContainer");
+        Container cmpContainer = containerSystem.getContainer("SpringDefinedCmpContainer");
         assertTrue("cmpContainer should be an instance of CmpContainer", cmpContainer instanceof org.apache.openejb.core.cmp.CmpContainer);
 
         //
-        // EJB
+        // JNDI Context
         //
-        Echo echo = (Echo) context.getBean("EchoBean");
-        assertNotNull("echo is null", echo);
-        assertEquals("olleH", echo.echo("Hello"));
-
         System.out.println();
         System.out.println();
         Debug.printContext(initialContext);
+        System.out.println();
+        System.out.println();
 
+        //
+        // EJB
+        //
+        Echo echo = (Echo) context.getBean("EchoBeanLocal");
+        assertNotNull("echo is null", echo);
+        assertEquals("olleH", echo.echo("Hello"));
+        echo = (Echo) context.getBean("Echo");
+        assertNotNull("echo is null", echo);
+        assertEquals("olleH", echo.echo("Hello"));
 
         //
         // Stop the Spring Context

Modified: openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml?rev=686455&r1=686454&r2=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml Fri Aug 15 23:22:43 2008
@@ -17,8 +17,7 @@
     limitations under the License.
 
 -->
-<beans default-lazy-init="true"
-        xmlns="http://www.springframework.org/schema/beans"
+<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:context="http://www.springframework.org/schema/context"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
@@ -28,48 +27,37 @@
 
     <context:annotation-config/>
 
-    <bean name="OpenEJB" class="org.apache.openejb.spring.OpenEJB">
-        <property name="containers">
-            <list>
-                <bean class="org.apache.openejb.spring.SingletonContainer">
-                    <property name="id" value="Spring Defined SingletonContainer"/>
-                    <property name="accessTimeout" value="45 sec"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.StatelessContainer">
-                    <property name="id" value="Spring Defined StatelessContainer"/>
-                    <property name="poolSize" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.StatefulContainer">
-                    <property name="id" value="Spring Defined StatefulContainer"/>
-                    <property name="poolSize" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.MdbContainer">
-                    <property name="id" value="Spring Defined MdbContainer"/>
-                    <property name="resourceAdapter" value="Spring Defined JMS Resource Adapter"/>
-                    <property name="instanceLimit" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.BmpContainer">
-                    <property name="id" value="Spring Defined BmpContainer"/>
-                    <property name="poolSize" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.CmpContainer">
-                    <property name="id" value="Spring Defined CmpContainer"/>
-                </bean>
-            </list>
-        </property>
-        <property name="resources">
-            <list>
-                <bean class="org.apache.openejb.spring.Resource">
-                    <property name="id" value="Spring Defined JMS Resource Adapter"/>
-                    <property name="type" value="ActiveMQResourceAdapter"/>
-                    <property name="properties">
-                        <props>
-                            <prop key="BrokerXmlConfig">broker:(tcp://localhost:61616)?useJmx=false</prop>
-                            <prop key="ServerUrl">vm://localhost?async=true</prop>
-                        </props>
-                    </property>
-                </bean>
-            </list>
+    <!-- OpenEJB instance is implicitly declared -->
+    <!--<bean name="OpenEJB" class="org.apache.openejb.spring.OpenEJB"/>-->
+
+    <!-- Containers -->
+    <bean name="SpringDefinedSingletonContainer" class="org.apache.openejb.spring.SingletonContainer">
+        <property name="accessTimeout" value="45 sec"/>
+    </bean>
+    <bean name="SpringDefinedStatelessContainer" class="org.apache.openejb.spring.StatelessContainer">
+        <property name="poolSize" value="50"/>
+    </bean>
+    <bean name="SpringDefinedStatefulContainer" class="org.apache.openejb.spring.StatefulContainer">
+        <property name="poolSize" value="50"/>
+    </bean>
+    <bean name="SpringDefinedMdbContainer" class="org.apache.openejb.spring.MdbContainer">
+        <property name="resourceAdapter" value="SpringDefinedJMSResourceAdapter"/>
+        <property name="instanceLimit" value="50"/>
+    </bean>
+    <bean name="SpringDefinedBmpContainer" class="org.apache.openejb.spring.BmpContainer">
+        <property name="poolSize" value="50"/>
+    </bean>
+    <bean name="SpringDefinedCmpContainer" class="org.apache.openejb.spring.CmpContainer">
+    </bean>
+
+    <!-- OpenEJB declared resouce adapter -->
+    <bean name="SpringDefinedJMSResourceAdapter" class="org.apache.openejb.spring.Resource">
+        <property name="type" value="ActiveMQResourceAdapter"/>
+        <property name="properties">
+            <props>
+                <prop key="BrokerXmlConfig">broker:(tcp://localhost:61616)?useJmx=false</prop>
+                <prop key="ServerUrl">vm://localhost?async=true</prop>
+            </props>
         </property>
     </bean>
 
@@ -86,20 +74,17 @@
         <property name="username" value="sa"/>
     </bean>
 
-    <!-- An Application containing all EJBs in the classloader -->
-    <bean name="classPathApplication" class="org.apache.openejb.spring.Application">
-        <property name="openEJB" ref="OpenEJB"/>
-    </bean>
+    <!-- Loads the Echo bean from the class path and exports it to this context -->
+    <bean name="classPathApplication" class="org.apache.openejb.spring.ClassPathApplication"/>
 
-    <!-- Deploys the classPathApplication, the EchoBean and return a proxy -->
-    <bean name="EchoBean" class="org.apache.openejb.spring.EJB">
-        <property name="application" ref="classPathApplication"/>
+    <!-- Explicit reference to the Echo bean... normally not needed -->
+    <bean name="Echo" class="org.apache.openejb.spring.EJB">
         <property name="deploymentId" value="EchoBean"/>
         <property name="interface" value="org.apache.openejb.spring.Echo"/>
     </bean>
 
     <!-- DataSource exported from OpenEJB -->
-    <bean id="openejbDS" class="org.apache.openejb.spring.OpenEJBDataSource" depends-on="OpenEJB">
+    <bean id="openejbDS" class="org.apache.openejb.spring.OpenEJBDataSource">
         <property name="resourceId" value="ds"/>
     </bean>
 </beans>
\ No newline at end of file

Copied: openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/test.xml (from r686050, openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml)
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/test.xml?p2=openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/test.xml&p1=openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml&r1=686050&r2=686455&rev=686455&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/spring.xml (original)
+++ openejb/trunk/openejb3/container/openejb-spring/src/test/resources/org/apache/openejb/spring/test.xml Fri Aug 15 23:22:43 2008
@@ -17,8 +17,7 @@
     limitations under the License.
 
 -->
-<beans default-lazy-init="true"
-        xmlns="http://www.springframework.org/schema/beans"
+<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:context="http://www.springframework.org/schema/context"
         xsi:schemaLocation="http://www.springframework.org/schema/beans
@@ -27,79 +26,10 @@
            http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
     <context:annotation-config/>
-
-    <bean name="OpenEJB" class="org.apache.openejb.spring.OpenEJB">
-        <property name="containers">
-            <list>
-                <bean class="org.apache.openejb.spring.SingletonContainer">
-                    <property name="id" value="Spring Defined SingletonContainer"/>
-                    <property name="accessTimeout" value="45 sec"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.StatelessContainer">
-                    <property name="id" value="Spring Defined StatelessContainer"/>
-                    <property name="poolSize" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.StatefulContainer">
-                    <property name="id" value="Spring Defined StatefulContainer"/>
-                    <property name="poolSize" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.MdbContainer">
-                    <property name="id" value="Spring Defined MdbContainer"/>
-                    <property name="resourceAdapter" value="Spring Defined JMS Resource Adapter"/>
-                    <property name="instanceLimit" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.BmpContainer">
-                    <property name="id" value="Spring Defined BmpContainer"/>
-                    <property name="poolSize" value="50"/>
-                </bean>
-                <bean class="org.apache.openejb.spring.CmpContainer">
-                    <property name="id" value="Spring Defined CmpContainer"/>
-                </bean>
-            </list>
-        </property>
-        <property name="resources">
-            <list>
-                <bean class="org.apache.openejb.spring.Resource">
-                    <property name="id" value="Spring Defined JMS Resource Adapter"/>
-                    <property name="type" value="ActiveMQResourceAdapter"/>
-                    <property name="properties">
-                        <props>
-                            <prop key="BrokerXmlConfig">broker:(tcp://localhost:61616)?useJmx=false</prop>
-                            <prop key="ServerUrl">vm://localhost?async=true</prop>
-                        </props>
-                    </property>
-                </bean>
-            </list>
-        </property>
-    </bean>
-
-    <!-- Spring declared TransactionManager which is automatically imported -->
-    <bean name="tm" class="org.apache.openejb.spring.MockTransactionManager"/>
-
-    <!-- Spring declared SecurityService which is automatically imported -->
-    <bean name="sec" class="org.apache.openejb.spring.MockSecurityService"/>
-
-    <!-- Spring declared DataSource which is imported into OpenEJB -->
-    <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
-        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
-        <property name="url" value="jdbc:hsqldb:file:data/hsqldb/hsqldb"/>
-        <property name="username" value="sa"/>
-    </bean>
-
-    <!-- An Application containing all EJBs in the classloader -->
-    <bean name="classPathApplication" class="org.apache.openejb.spring.Application">
-        <property name="openEJB" ref="OpenEJB"/>
-    </bean>
-
-    <!-- Deploys the classPathApplication, the EchoBean and return a proxy -->
-    <bean name="EchoBean" class="org.apache.openejb.spring.EJB">
-        <property name="application" ref="classPathApplication"/>
-        <property name="deploymentId" value="EchoBean"/>
-        <property name="interface" value="org.apache.openejb.spring.Echo"/>
+    <bean name="next" class="org.apache.openejb.spring.LinkedBean">
     </bean>
 
-    <!-- DataSource exported from OpenEJB -->
-    <bean id="openejbDS" class="org.apache.openejb.spring.OpenEJBDataSource" depends-on="OpenEJB">
-        <property name="resourceId" value="ds"/>
+    <bean name="first" class="org.apache.openejb.spring.LinkedBean">
+        <property name="next" ref="nextBean"/>
     </bean>
 </beans>
\ No newline at end of file