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 2007/01/26 08:38:58 UTC

svn commit: r500168 - in /incubator/openejb/trunk/openejb3: assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/ container/openejb-core/src/main/java/org/apache/openejb/ container/openejb-core/src/main/java/org/apache/openejb/alt/containers...

Author: dblevins
Date: Thu Jan 25 23:38:56 2007
New Revision: 500168

URL: http://svn.apache.org/viewvc?view=rev&rev=500168
Log:
OPENEJB-446: App undeploy

Added:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/NoSuchApplicationException.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/UndeployException.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/naming/
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/naming/IvmContextTest.java
Modified:
    incubator/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatJndiSupport.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/Container.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreContainerSystem.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/Cmp2EntityContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityInstanceManager.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbObjectProxyHandler.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/IvmContext.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/NameNode.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java

Modified: incubator/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatJndiSupport.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatJndiSupport.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatJndiSupport.java (original)
+++ incubator/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatJndiSupport.java Thu Jan 25 23:38:56 2007
@@ -56,8 +56,8 @@
     public void init(Object containerId, HashMap deployments, Properties properties) throws OpenEJBException {
     }
 
-    public void deploy(Object deploymentID, org.apache.openejb.DeploymentInfo info) throws OpenEJBException {
-        super.deploy(deploymentID, info);
+    public void deploy(org.apache.openejb.DeploymentInfo info) throws OpenEJBException {
+        super.deploy(info);
         setupDeployment((org.apache.openejb.core.CoreDeploymentInfo) info);
     }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/Container.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/Container.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/Container.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/Container.java Thu Jan 25 23:38:56 2007
@@ -26,5 +26,7 @@
 
     public DeploymentInfo [] deployments();
 
-    public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException;
+    public void deploy(DeploymentInfo info) throws OpenEJBException;
+
+    public void undeploy(DeploymentInfo info) throws OpenEJBException;
 }

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/NoSuchApplicationException.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/NoSuchApplicationException.java?view=auto&rev=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/NoSuchApplicationException.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/NoSuchApplicationException.java Thu Jan 25 23:38:56 2007
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class NoSuchApplicationException extends OpenEJBException {
+    public NoSuchApplicationException() {
+    }
+
+    public NoSuchApplicationException(String message) {
+        super(message);
+    }
+
+    public NoSuchApplicationException(String message, Throwable rootCause) {
+        super(message, rootCause);
+    }
+
+    public NoSuchApplicationException(Throwable rootCause) {
+        super(rootCause);
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java Thu Jan 25 23:38:56 2007
@@ -284,6 +284,6 @@
      * 1 usages
      */
     public static boolean isInitialized() {
-        return instance != null;
+        return instance != null || SystemInstance.get().getComponent(ContainerSystem.class) != null;
     }
 }

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/UndeployException.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/UndeployException.java?view=auto&rev=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/UndeployException.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/UndeployException.java Thu Jan 25 23:38:56 2007
@@ -0,0 +1,47 @@
+/**
+ * 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;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class UndeployException extends OpenEJBException {
+
+    private final List<Throwable> causes = new ArrayList<Throwable>();
+
+    public UndeployException() {
+    }
+
+    public UndeployException(String message) {
+        super(message);
+    }
+
+    public UndeployException(String message, Throwable rootCause) {
+        super(message, rootCause);
+    }
+
+    public UndeployException(Throwable rootCause) {
+        super(rootCause);
+    }
+
+    public List<Throwable> getCauses() {
+        return causes;
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/containers/castor_cmp11/CastorCmpEngine.java Thu Jan 25 23:38:56 2007
@@ -66,6 +66,7 @@
     private final JDOManager globalJdoManager;
     private final CmpCallback cmpCallback;
     private final JndiTxReference txReference;
+    private final Map<Object, CoreDeploymentInfo> deployments = new HashMap<Object, CoreDeploymentInfo>();
 
     private final Map<String,String> abstractSchemaMap = new HashMap<String,String>();
 
@@ -132,11 +133,24 @@
     }
 
     public void deploy(CoreDeploymentInfo deploymentInfo) throws SystemException {
+        deployments.put(deploymentInfo.getDeploymentID(), deploymentInfo);
         bindTransactionManagerReference(deploymentInfo);
         configureKeyGenerator(deploymentInfo);
         String beanClassName = deploymentInfo.getBeanClass().getName();
         String abstractSchemaName = beanClassName.substring(beanClassName.lastIndexOf('.') + 1);
         abstractSchemaMap.put(abstractSchemaName, beanClassName);
+    }
+
+    public void undeploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        deploymentInfo.setKeyGenerator(null);
+        deployments.remove(deploymentInfo.getDeploymentID());
+        if (deployments.size() == 0){
+            abstractSchemaMap.clear();
+        }
+    }
+
+    public boolean isEmpty() {
+        return deployments.size() == 0;
     }
 
     public Object createBean(EntityBean bean, ThreadContext callContext) throws CreateException {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Thu Jan 25 23:38:56 2007
@@ -18,11 +18,13 @@
 
 import org.apache.openejb.Container;
 import org.apache.openejb.DeploymentInfo;
+import org.apache.openejb.DuplicateDeploymentIdException;
 import org.apache.openejb.EnvProps;
 import org.apache.openejb.Injection;
+import org.apache.openejb.NoSuchApplicationException;
 import org.apache.openejb.OpenEJB;
 import org.apache.openejb.OpenEJBException;
-import org.apache.openejb.DuplicateDeploymentIdException;
+import org.apache.openejb.UndeployException;
 import org.apache.openejb.core.ConnectorReference;
 import org.apache.openejb.core.CoreContainerSystem;
 import org.apache.openejb.core.CoreDeploymentInfo;
@@ -35,6 +37,8 @@
 import org.apache.openejb.persistence.PersistenceClassLoaderHandler;
 import org.apache.openejb.persistence.PersistenceDeployer;
 import org.apache.openejb.persistence.PersistenceDeployerException;
+import org.apache.openejb.spi.ApplicationServer;
+import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.OpenEJBErrorHandler;
@@ -53,7 +57,6 @@
 import javax.resource.spi.ManagedConnectionFactory;
 import javax.transaction.TransactionManager;
 import javax.transaction.TransactionSynchronizationRegistry;
-import javax.ejb.DuplicateKeyException;
 import java.io.File;
 import java.io.IOException;
 import java.lang.instrument.ClassFileTransformer;
@@ -99,13 +102,21 @@
 
         installNaming();
 
+        SystemInstance system = SystemInstance.get();
+
         containerSystem = new CoreContainerSystem();
+        system.setComponent(ContainerSystem.class, containerSystem);
 
         jndiBuilder = new JndiBuilder(containerSystem.getJNDIContext());
 
         setConfiguration(new OpenEjbConfiguration());
 
-        SystemInstance.get().setComponent(Assembler.class, this);
+        ApplicationServer appServer = system.getComponent(ApplicationServer.class);
+        if (appServer == null) {
+            system.setComponent(ApplicationServer.class, new org.apache.openejb.core.ServerFederation());
+        }
+
+
     }
 
     private void setConfiguration(OpenEjbConfiguration config) {
@@ -267,7 +278,7 @@
             } catch (DuplicateDeploymentIdException e) {
                 // already logged.
             } catch (Throwable e) {
-                logger.error("Application could not be deployed: "+appInfo.jarPath, e);
+                logger.error("Application could not be deployed: " + appInfo.jarPath, e);
             }
         }
     }
@@ -305,19 +316,19 @@
         List<String> used = new ArrayList();
         for (EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
             for (EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) {
-                if (containerSystem.getDeploymentInfo(beanInfo.ejbDeploymentId) != null){
+                if (containerSystem.getDeploymentInfo(beanInfo.ejbDeploymentId) != null) {
                     used.add(beanInfo.ejbDeploymentId);
                 }
             }
         }
 
-        if (used.size() > 0){
+        if (used.size() > 0) {
             String message = "Application cannot be deployed as it contains deployment-ids which are already deployed: app: " + appInfo.jarPath;
             logger.error(message);
             OpenEJBException openEJBException = new DuplicateDeploymentIdException(message);
             Exception e = openEJBException;
             for (String id : used) {
-                logger.debug("DeploymentId already used: "+id);
+                logger.debug("DeploymentId already used: " + id);
                 DuplicateDeploymentIdException e2 = new DuplicateDeploymentIdException(id);
                 e.initCause(e2);
                 e = e2;
@@ -329,9 +340,11 @@
         Cmp2Builder cmp2Builder = new Cmp2Builder(appInfo, classLoader);
         File generatedJar = cmp2Builder.getJarFile();
         if (generatedJar != null) {
-            classLoader = new URLClassLoader(new URL [] {generatedJar.toURL()}, classLoader);
+            classLoader = new URLClassLoader(new URL []{generatedJar.toURL()}, classLoader);
         }
 
+        AssemblyUnit unit = new AssemblyUnit(appInfo.jarPath);
+        assemblyUnits.put(appInfo.jarPath, unit);
 
         // JPA - Persistence Units MUST be processed first since they will add ClassFileTransformers
         // to the class loader which must be added before any classes are loaded
@@ -361,6 +374,7 @@
                 applyTransactionAttributes((CoreDeploymentInfo) deploymentInfo, ejbJar.methodTransactions);
                 containerSystem.addDeployment(deploymentInfo);
                 jndiBuilder.bind(deploymentInfo);
+                unit.deployments.add((CoreDeploymentInfo) deploymentInfo);
             }
 
             for (EnterpriseBeanInfo beanInfo : ejbJar.enterpriseBeans) {
@@ -371,6 +385,7 @@
 
         // App Client
         for (ClientInfo clientInfo : appInfo.clients) {
+            unit.clientIds.add(clientInfo.moduleId);
             JndiEncBuilder jndiEncBuilder = new JndiEncBuilder(clientInfo.jndiEnc);
             Context context = (Context) jndiEncBuilder.build().lookup("env");
             containerSystem.getJNDIContext().bind("java:openejb/client/" + clientInfo.moduleId + "/comp/env", context);
@@ -397,6 +412,15 @@
         }
     }
 
+    public void destroyApplication(String filePath) throws Exception {
+        AssemblyUnit unit = assemblyUnits.get(filePath);
+        if (unit == null) {
+            throw new NoSuchApplicationException(filePath);
+        }
+        unit.destroy();
+        assemblyUnits.remove(filePath);
+    }
+
     public ClassLoader createAppClassLoader(AppInfo appInfo) throws OpenEJBException, IOException {
         List<URL> jars = new ArrayList<URL>();
         for (EjbJarInfo info : appInfo.ejbJars) {
@@ -657,6 +681,71 @@
 
         public ClassLoader getNewTempClassLoader(ClassLoader classLoader) {
             return new TemporaryClassLoader(classLoader);
+        }
+    }
+
+    private final Map<String, AssemblyUnit> assemblyUnits = new HashMap<String, AssemblyUnit>();
+
+    private final class AssemblyUnit {
+        private final List<CoreDeploymentInfo> deployments = new ArrayList<CoreDeploymentInfo>();
+        private final List<String> clientIds = new ArrayList<String>();
+        private final String appId;
+
+        public AssemblyUnit(String appId) {
+            this.appId = appId;
+        }
+
+        private void destroy() throws Exception {
+            Context globalContext = containerSystem.getJNDIContext();
+            UndeployException undeployException = new UndeployException("Failed undeploying application: id=" + appId);
+            // Clear out naming for all components first
+            for (CoreDeploymentInfo deployment : deployments) {
+                String deploymentID = deployment.getDeploymentID() + "";
+                try {
+                    containerSystem.removeDeploymentInfo(deployment);
+                } catch (Throwable t) {
+                    undeployException.getCauses().add(new Exception(deploymentID, t));
+                }
+
+                JndiBuilder.Bindings bindings = deployment.get(JndiBuilder.Bindings.class);
+                for (String name : bindings.getBindings()) {
+                    try {
+                        globalContext.lookup("openejb/ejb/" + name);
+                        globalContext.unbind("/openejb/ejb/" + name);
+                        try {
+                            globalContext.lookup("openejb/ejb/" + name);
+                            throw new OpenEJBException("Unbind failed: " + name);
+                        } catch (NamingException goodAndExpected) {
+                        }
+                    } catch (Throwable t) {
+                        undeployException.getCauses().add(new Exception("bean: " + deploymentID, t));
+                    }
+                }
+            }
+            for (CoreDeploymentInfo deployment : deployments) {
+                String deploymentID = deployment.getDeploymentID() + "";
+                try {
+                    Container container = deployment.getContainer();
+                    container.undeploy(deployment);
+                    deployment.setContainer(null);
+                } catch (Throwable t) {
+                    undeployException.getCauses().add(new Exception("bean: " + deploymentID, t));
+                } finally {
+                    deployment.setDestroyed(true);
+                }
+            }
+            deployments.clear();
+
+            for (String clientId : clientIds) {
+                try {
+                    globalContext.unbind("/openejb/client/" + clientId);
+                } catch (Throwable t) {
+                    undeployException.getCauses().add(new Exception("client: " + clientId, t));
+                }
+            }
+            if (undeployException.getCauses().size() > 0) {
+                throw undeployException;
+            }
         }
     }
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java Thu Jan 25 23:38:56 2007
@@ -55,7 +55,7 @@
 
                 Container container = (Container) props.get(ejbInfo.containerId);
                 if (container == null) throw new IllegalStateException("Container does not exist: "+ejbInfo.containerId +".  Referenced by deployment: "+deployment.getDeploymentID());
-                container.deploy(deployment.getDeploymentID(), deployment);
+                container.deploy(deployment);
                 deployment.setContainer(container);
             } catch (Throwable e) {
                 throw new OpenEJBException("Error building bean '"+ejbInfo.ejbName+"'.  Exception: "+e.getClass()+": "+e.getMessage(), e);

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiBuilder.java Thu Jan 25 23:38:56 2007
@@ -30,6 +30,9 @@
 import org.apache.openejb.core.stateful.StatefulEncReference;
 import org.apache.openejb.core.stateless.StatelessEncReference;
 
+import java.util.List;
+import java.util.ArrayList;
+
 
 /**
  * @version $Rev$ $Date$
@@ -129,13 +132,17 @@
     }
 
     public void bind(DeploymentInfo deploymentInfo) {
-
         CoreDeploymentInfo deployment = (CoreDeploymentInfo) deploymentInfo;
+
+        Bindings bindings = new Bindings();
+        deployment.set(Bindings.class, bindings);
+
         Object id = deployment.getDeploymentID();
         try {
             Class homeInterface = deployment.getHomeInterface();
             if (homeInterface != null) {
                 String name = strategy.getName(deployment, homeInterface, JndiNameStrategy.Interface.REMOTE_HOME);
+                bindings.add(name);
                 context.bind("openejb/ejb/" + name, getReference(deployment.getEJBHome(), deployment));
             }
         } catch (NamingException e) {
@@ -146,6 +153,7 @@
             Class localHomeInterface = deployment.getLocalHomeInterface();
             if (localHomeInterface != null) {
                 String name = strategy.getName(deployment, localHomeInterface, JndiNameStrategy.Interface.LOCAL_HOME);
+                bindings.add(name);
                 context.bind("openejb/ejb/" + name, getReference(deployment.getEJBLocalHome(), deployment));
             }
         } catch (NamingException e) {
@@ -157,6 +165,7 @@
             if (businessLocalInterface != null) {
                 String name = strategy.getName(deployment, businessLocalInterface, JndiNameStrategy.Interface.BUSINESS_LOCAL);
                 DeploymentInfo.BusinessLocalHome businessLocalHome = deployment.getBusinessLocalHome();
+                bindings.add(name);
                 context.bind("openejb/ejb/" + name, new BusinessLocalReference(businessLocalHome));
             }
         } catch (NamingException e) {
@@ -168,6 +177,7 @@
             if (businessRemoteInterface != null) {
                 String name = strategy.getName(deployment, businessRemoteInterface, JndiNameStrategy.Interface.BUSINESS_REMOTE);
                 DeploymentInfo.BusinessRemoteHome businessRemoteHome = deployment.getBusinessRemoteHome();
+                bindings.add(name);
                 context.bind("openejb/ejb/" + name, new BusinessRemoteReference(businessRemoteHome));
             }
         } catch (NamingException e) {
@@ -186,5 +196,17 @@
             ref = new EntityEncReference(ref);
         }
         return ref;
+    }
+
+    protected static final class Bindings {
+        private final List<String> bindings = new ArrayList<String>();
+
+        public List<String> getBindings() {
+            return bindings;
+        }
+
+        public boolean add(String o) {
+            return bindings.add(o);
+        }
     }
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java Thu Jan 25 23:38:56 2007
@@ -50,9 +50,9 @@
 
     public void init(Properties properties) throws Exception {
         if (openejb != null) return;
-        SystemInstance.init(properties);
         openejb = new OpenEJBInstance();
         if (openejb.isInitialized()) return;
+        SystemInstance.init(properties);
         openejb.init(properties);
         if (properties.getProperty(OPENEJB_EMBEDDED_REMOTABLE, "false").equalsIgnoreCase("true")){
             bootServerServices();

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreContainerSystem.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreContainerSystem.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreContainerSystem.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreContainerSystem.java Thu Jan 25 23:38:56 2007
@@ -74,6 +74,10 @@
 
     }
 
+    public void removeDeploymentInfo(DeploymentInfo info){
+        this.deployments.remove(info.getDeploymentID());
+    }
+
 
     public javax.naming.Context getJNDIContext() {
         return jndiRootContext;

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java Thu Jan 25 23:38:56 2007
@@ -71,6 +71,7 @@
  */
 public class CoreDeploymentInfo implements org.apache.openejb.DeploymentInfo {
 
+    private boolean destroyed;
     private Class homeInterface;
     private Class remoteInterface;
     private Class localHomeInterface;
@@ -212,6 +213,14 @@
             }
         }
         createMethodMap();
+    }
+
+    public boolean isDestroyed() {
+        return destroyed;
+    }
+
+    public void setDestroyed(boolean destroyed) {
+        this.destroyed = destroyed;
     }
 
     @SuppressWarnings({"unchecked"})

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java Thu Jan 25 23:38:56 2007
@@ -51,8 +51,12 @@
         return container.deployments();
     }
 
-    public void deploy(Object deploymentID, org.apache.openejb.DeploymentInfo info) throws OpenEJBException {
-        container.deploy(deploymentID, info);
+    public void deploy(org.apache.openejb.DeploymentInfo info) throws OpenEJBException {
+        container.deploy(info);
+    }
+
+    public void undeploy(org.apache.openejb.DeploymentInfo info) throws OpenEJBException {
+        container.undeploy(info);
     }
 
     public void discardInstance(Object instance, ThreadContext context) {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java Thu Jan 25 23:38:56 2007
@@ -119,10 +119,36 @@
         return deploymentsByClass.get(beanType);
     }
 
-    public void deploy(Object deploymentID, DeploymentInfo deploymentInfo) throws OpenEJBException {
+    public void deploy(DeploymentInfo deploymentInfo) throws OpenEJBException {
         deploy((CoreDeploymentInfo) deploymentInfo);
     }
 
+    public void undeploy(DeploymentInfo deploymentInfo) throws OpenEJBException {
+        undeploy((CoreDeploymentInfo)deploymentInfo);
+    }
+
+    public synchronized void undeploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        deploymentsById.remove(deploymentInfo.getDeploymentID());
+        deploymentsByClass.remove(deploymentInfo.getCmpBeanImpl());
+
+        try {
+            Field field = deploymentInfo.getCmpBeanImpl().getField("deploymentInfo");
+            field.set(null, null);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        CmpEngine cmpEngine = (CmpEngine) deploymentInfo.getContainerData();
+        cmpEngine.undeploy(deploymentInfo);
+
+        if (cmpEngine.isEmpty()){
+            cmpEngines.remove(deploymentInfo.getJarPath());
+            cmpEngines.remove(deploymentInfo.getClassLoader());
+        }
+        deploymentInfo.setContainer(null);
+        deploymentInfo.setContainerData(null);
+    }
+
     public synchronized void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
         Object deploymentId = deploymentInfo.getDeploymentID();
 
@@ -195,6 +221,7 @@
 
     public Object invoke(Object deployID, Method callMethod, Object[] args, Object primKey, Object securityIdentity) throws OpenEJBException {
         CoreDeploymentInfo deployInfo = (CoreDeploymentInfo) this.getDeploymentInfo(deployID);
+        if (deployInfo == null) throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='"+deployID+"'), Container(id='"+containerID+"')");
         ThreadContext callContext = new ThreadContext(deployInfo, primKey, securityIdentity);
 
         ThreadContext oldCallContext = ThreadContext.enter(callContext);

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpEngine.java Thu Jan 25 23:38:56 2007
@@ -40,4 +40,8 @@
     List<Object> queryBeans(ThreadContext callContext, String queryString, Object[] args) throws FinderException;
 
     void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException;
+
+    void undeploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException;
+
+    boolean isEmpty();
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/cmp2/Cmp2Util.java Thu Jan 25 23:38:56 2007
@@ -51,7 +51,7 @@
             throw new IllegalArgumentException("Proxy is not connected to a CMP container but is conect to " + handler.container.getClass().getName());
         }
         CmpContainer container = (CmpContainer) handler.container;
-        Bean entity = (Bean) container.getEjbInstance(handler.deploymentInfo, handler.primaryKey);
+        Bean entity = (Bean) container.getEjbInstance(handler.getDeploymentInfo(), handler.primaryKey);
         return entity;
     }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java Thu Jan 25 23:38:56 2007
@@ -21,6 +21,8 @@
 import java.util.List;
 import java.util.Set;
 import java.util.WeakHashMap;
+import java.util.Map;
+import java.util.HashMap;
 import javax.ejb.CreateException;
 import javax.ejb.EJBException;
 import javax.ejb.EJBObject;
@@ -53,6 +55,7 @@
     private final CmpCallback cmpCallback;
     private final WeakHashMap<EntityManager,Object> entityManagerListeners = new WeakHashMap<EntityManager,Object>();
 
+    private final Map<Object, CoreDeploymentInfo> deployments = new HashMap<Object, CoreDeploymentInfo>();
     private final ThreadLocal<Set<EntityBean>> creating = new ThreadLocal<Set<EntityBean>>() {
         protected Set<EntityBean> initialValue() {
             return new HashSet<EntityBean>();
@@ -64,6 +67,7 @@
     }
 
     public void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        deployments.put(deploymentInfo.getDeploymentID(), deploymentInfo);
         Class beanClass = deploymentInfo.getBeanClass();
         if (deploymentInfo.isCmp2()) {
             String beanClassName = beanClass.getName();
@@ -79,6 +83,18 @@
             deploymentInfo.setCmpBeanImpl(beanClass);
         }
         configureKeyGenerator(deploymentInfo);
+    }
+
+    public void undeploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        deploymentInfo.setKeyGenerator(null);
+        deployments.remove(deploymentInfo.getDeploymentID());
+        if (deployments.size() == 0){
+            entityManagerListeners.clear();
+        }
+    }
+
+    public boolean isEmpty() {
+        return deployments.size() == 0;
     }
 
     private EntityManager getEntityManager(CoreDeploymentInfo deploymentInfo) {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/Cmp2EntityContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/Cmp2EntityContainer.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/Cmp2EntityContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/Cmp2EntityContainer.java Thu Jan 25 23:38:56 2007
@@ -16,7 +16,6 @@
  */
 package org.apache.openejb.core.entity;
 
-import org.apache.openejb.Container;
 import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.ContainerType;
@@ -46,12 +45,16 @@
         return null;
     }
 
-    public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException {
+    public void deploy(DeploymentInfo info) throws OpenEJBException {
         Map registry = new HashMap(deploymentRegistry);
-        registry.put(deploymentID, info);
+        registry.put(info.getDeploymentID(), info);
         deploymentRegistry = registry;
         org.apache.openejb.core.CoreDeploymentInfo di = (org.apache.openejb.core.CoreDeploymentInfo) info;
         di.setContainer(this);
+    }
+
+    public void undeploy(DeploymentInfo info) throws OpenEJBException {
+        deploymentRegistry.remove(info.getDeploymentID());
     }
 
     public DeploymentInfo [] deployments() {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContainer.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContainer.java Thu Jan 25 23:38:56 2007
@@ -82,17 +82,25 @@
         return containerID;
     }
 
-    public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException {
+    public void deploy(DeploymentInfo info) throws OpenEJBException {
         Map registry = new HashMap(deploymentRegistry);
-        registry.put(deploymentID, info);
+        registry.put(info.getDeploymentID(), info);
         deploymentRegistry = registry;
         org.apache.openejb.core.CoreDeploymentInfo di = (org.apache.openejb.core.CoreDeploymentInfo) info;
         di.setContainer(this);
         instanceManager.deploy(info);
     }
 
+    public void undeploy(DeploymentInfo info) throws OpenEJBException {
+        deploymentRegistry.remove(info.getDeploymentID());
+        instanceManager.undeploy(info);
+        info.setContainer(null);
+    }
+
     public Object invoke(Object deployID, Method callMethod, Object [] args, Object primKey, Object securityIdentity) throws org.apache.openejb.OpenEJBException {
         CoreDeploymentInfo deployInfo = (CoreDeploymentInfo) this.getDeploymentInfo(deployID);
+        if (deployInfo == null) throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='"+deployID+"'), Container(id='"+containerID+"')");
+        
         ThreadContext callContext = new ThreadContext(deployInfo, primKey, securityIdentity);
         ThreadContext oldCallContext = ThreadContext.enter(callContext);
         try {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityInstanceManager.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityInstanceManager.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityInstanceManager.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityInstanceManager.java Thu Jan 25 23:38:56 2007
@@ -80,6 +80,10 @@
         poolMap.put(deploymentInfo.getDeploymentID(), new LinkedListStack(poolsize / 2));
     }
 
+    public void undeploy(org.apache.openejb.DeploymentInfo deploymentInfo) {
+        poolMap.remove(deploymentInfo.getDeploymentID());
+    }
+
     public EntityBean obtainInstance(ThreadContext callContext)
             throws OpenEJBException {
         Transaction currentTx = null;

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java Thu Jan 25 23:38:56 2007
@@ -24,11 +24,11 @@
 import java.io.ByteArrayInputStream;
 import java.io.ObjectInputStream;
 import java.lang.reflect.Method;
+import java.lang.ref.WeakReference;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.Properties;
 
 import javax.ejb.EJBException;
@@ -40,7 +40,6 @@
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.ThreadContext;
-import org.apache.openejb.core.Operation;
 import org.apache.openejb.util.proxy.InvocationHandler;
 import org.apache.openejb.util.proxy.ProxyManager;
 
@@ -53,7 +52,7 @@
 
     public boolean inProxyMap = false;
 
-    public transient CoreDeploymentInfo deploymentInfo;
+    private transient WeakReference<CoreDeploymentInfo> deploymentInfo;
 
     public transient RpcContainer container;
 
@@ -81,7 +80,7 @@
         this.container = container;
         this.primaryKey = pk;
         this.deploymentID = depID;
-        this.deploymentInfo = (org.apache.openejb.core.CoreDeploymentInfo) container.getDeploymentInfo(depID);
+        this.setDeploymentInfo((CoreDeploymentInfo) container.getDeploymentInfo(depID));
 
         Properties properties = SystemInstance.get().getProperties();
         String value = properties.getProperty("openejb.localcopy");
@@ -96,13 +95,13 @@
         in.defaultReadObject();
 
         ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
-        deploymentInfo = (org.apache.openejb.core.CoreDeploymentInfo) containerSystem.getDeploymentInfo(deploymentID);
-        container = (RpcContainer) deploymentInfo.getContainer();
+        setDeploymentInfo((CoreDeploymentInfo) containerSystem.getDeploymentInfo(deploymentID));
+        container = (RpcContainer) getDeploymentInfo().getContainer();
     }
 
     protected void checkAuthorization(Method method) throws org.apache.openejb.OpenEJBException {
         Object caller = getThreadSpecificSecurityIdentity();
-        boolean authorized = getSecurityService().isCallerAuthorized(caller, deploymentInfo.getAuthorizedRoles(method));
+        boolean authorized = getSecurityService().isCallerAuthorized(caller, getDeploymentInfo().getAuthorizedRoles(method));
         if (!authorized)
             throw new org.apache.openejb.ApplicationException(new RemoteException("Unauthorized Access by Principal Denied"));
     }
@@ -126,6 +125,7 @@
 
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         if (isInvalidReference) throw new NoSuchObjectException("reference is invalid");
+        getDeploymentInfo(); // will throw an exception if app has been undeployed.
 
         if (method.getDeclaringClass() == Object.class) {
             final String methodName = method.getName();
@@ -305,7 +305,7 @@
 
     public void invalidateReference() {
         this.container = null;
-        this.deploymentInfo = null;
+        this.setDeploymentInfo(null);
         this.isInvalidReference = true;
     }
 
@@ -343,5 +343,18 @@
     public void setLocal(boolean isLocal) {
         this.isLocal = isLocal;
         this.doIntraVmCopy = !isLocal;
+    }
+
+    public CoreDeploymentInfo getDeploymentInfo() {
+        CoreDeploymentInfo info = deploymentInfo.get();
+        if (info == null|| info.isDestroyed()){
+            invalidateReference();
+            throw new IllegalStateException("Bean '"+deploymentID+"' has been undeployed.");
+        }
+        return info;
+    }
+
+    public void setDeploymentInfo(CoreDeploymentInfo deploymentInfo) {
+        this.deploymentInfo = new WeakReference<CoreDeploymentInfo>(deploymentInfo);
     }
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java Thu Jan 25 23:38:56 2007
@@ -30,7 +30,6 @@
 import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ApplicationServer;
-import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.util.proxy.ProxyManager;
 
 public abstract class EjbHomeProxyHandler extends BaseEjbProxyHandler {
@@ -226,7 +225,7 @@
 
     protected Object getEJBMetaData(Method method, Object[] args, Object proxy) throws Throwable {
         checkAuthorization(method);
-        IntraVmMetaData metaData = new IntraVmMetaData(deploymentInfo.getHomeInterface(), deploymentInfo.getRemoteInterface(), deploymentInfo.getPrimaryKeyClass(), deploymentInfo.getComponentType());
+        IntraVmMetaData metaData = new IntraVmMetaData(getDeploymentInfo().getHomeInterface(), getDeploymentInfo().getRemoteInterface(), getDeploymentInfo().getPrimaryKeyClass(), getDeploymentInfo().getComponentType());
         metaData.setEJBHome((EJBHome) proxy);
         return metaData;
     }
@@ -237,7 +236,7 @@
     }
 
     public org.apache.openejb.ProxyInfo getProxyInfo() {
-        return new org.apache.openejb.ProxyInfo(deploymentInfo, null, deploymentInfo.getHomeInterface(), container, interfaceType);
+        return new org.apache.openejb.ProxyInfo(getDeploymentInfo(), null, getDeploymentInfo().getHomeInterface(), container, interfaceType);
     }
 
     protected Object _writeReplace(Object proxy) throws ObjectStreamException {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbObjectProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbObjectProxyHandler.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbObjectProxyHandler.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbObjectProxyHandler.java Thu Jan 25 23:38:56 2007
@@ -133,12 +133,12 @@
 
     protected Object getEJBHome(Method method, Object[] args, Object proxy) throws Throwable {
         checkAuthorization(method);
-        return deploymentInfo.getEJBHome();
+        return getDeploymentInfo().getEJBHome();
     }
 
     protected Object getEJBLocalHome(Method method, Object[] args, Object proxy) throws Throwable {
         checkAuthorization(method);
-        return deploymentInfo.getEJBLocalHome();
+        return getDeploymentInfo().getEJBLocalHome();
     }
 
     protected Object getHandle(Method method, Object[] args, Object proxy) throws Throwable {
@@ -147,7 +147,7 @@
     }
 
     public org.apache.openejb.ProxyInfo getProxyInfo() {
-        return new org.apache.openejb.ProxyInfo(deploymentInfo, primaryKey, deploymentInfo.getInterface(interfaceType), container, interfaceType);
+        return new org.apache.openejb.ProxyInfo(getDeploymentInfo(), primaryKey, getDeploymentInfo().getInterface(interfaceType), container, interfaceType);
     }
 
     protected Object _writeReplace(Object proxy) throws ObjectStreamException {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/IvmContext.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/IvmContext.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/IvmContext.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/IvmContext.java Thu Jan 25 23:38:56 2007
@@ -281,7 +281,19 @@
     }
 
     public void unbind(String name) throws NamingException {
-        throw new javax.naming.OperationNotSupportedException();
+        checkReadOnly();
+        int indx = name.indexOf(":");
+        if (indx > -1) {
+            /*
+             The ':' character will be in the path if its an absolute path name starting with the schema
+             'java:'.  We strip the schema off the path before passing it to the node.resolve method.
+            */
+            name = name.substring(indx + 1);
+        }
+        fastCache.clear();
+        mynode.clearCache();
+
+        mynode.unbind(new ParsedName(name));
     }
 
     public void unbind(Name name) throws NamingException {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/NameNode.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/NameNode.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/NameNode.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/NameNode.java Thu Jan 25 23:38:56 2007
@@ -25,7 +25,7 @@
     public NameNode parent;
     public Object myObject;
     public transient IvmContext myContext;
-
+    boolean unbound;
     public NameNode(NameNode parent, ParsedName name, Object obj) {
         atomicName = name.getComponent();
         atomicHash = name.getComponentHashCode();
@@ -53,8 +53,11 @@
             if (name.next()) {
                 if (subTree == null) throw new javax.naming.NameNotFoundException("Can not resolve " + name);
                 return subTree.resolve(name);
-            } else
+            } else if (unbound){
+                throw new javax.naming.NameNotFoundException("Can not resolve " + name);
+            } else {
                 return getBinding();
+            }
         } else if (compareResult == ParsedName.IS_LESS) {// parsed hash is less than
             if (lessTree == null) throw new javax.naming.NameNotFoundException("Can not resolve " + name);
             return lessTree.resolve(name);
@@ -81,6 +84,7 @@
                 if (subTree != null) {
                     throw new javax.naming.NameAlreadyBoundException();
                 }
+                unbound = false;
                 myObject = obj;// bind the object to this node
             }
         } else if (compareResult == ParsedName.IS_LESS) {
@@ -94,6 +98,42 @@
                 grtrTree = new NameNode(this.parent, name, obj);
             else
                 grtrTree.bind(name, obj);
+        }
+    }
+
+    public void unbind(ParsedName name) throws javax.naming.NameAlreadyBoundException {
+        int compareResult = name.compareTo(atomicHash);
+        if (compareResult == ParsedName.IS_EQUAL && name.getComponent().equals(atomicName)) {
+            if (name.next()) {
+                if (subTree != null)
+                    subTree.unbind(name);
+            } else {
+                unbound = true;
+                myObject = null;
+            }
+        } else if (compareResult == ParsedName.IS_LESS) {
+            if (lessTree != null) {
+                lessTree.unbind(name);
+            }
+        } else {//ParsedName.IS_GREATER ...
+
+            if (grtrTree != null)
+                grtrTree.unbind(name);
+        }
+    }
+
+    protected void clearCache() {
+        if (myContext != null) {
+            myContext.fastCache.clear();
+        }
+        if (grtrTree != null) {
+            grtrTree.clearCache();
+        }
+        if (lessTree != null){
+            lessTree.clearCache();
+        }
+        if (subTree != null){
+            subTree.clearCache();
         }
     }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java Thu Jan 25 23:38:56 2007
@@ -82,11 +82,15 @@
         return containerID;
     }
 
-    public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException {
+    public void deploy(DeploymentInfo info) throws OpenEJBException {
+    }
+
+    public void undeploy(DeploymentInfo info) throws OpenEJBException {
     }
 
     // TODO: DMB: Temporarily commenting out as it locks the VM
-    public void LOCKUP_deploy(Object deploymentId, DeploymentInfo deploymentInfo) throws OpenEJBException {
+    public void LOCKUP_deploy(DeploymentInfo deploymentInfo) throws OpenEJBException {
+        Object deploymentId = deploymentInfo.getDeploymentID();
         // create the activation spec
         ActivationSpec activationSpec = createActivationSpec(deploymentInfo);
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java Thu Jan 25 23:38:56 2007
@@ -198,20 +198,31 @@
         return deploymentsById.get(deploymentID);
     }
 
-    public void deploy(Object deploymentId, DeploymentInfo deploymentInfo) throws OpenEJBException {
-        deploy(deploymentId, (CoreDeploymentInfo)deploymentInfo);
+    public void deploy(DeploymentInfo deploymentInfo) throws OpenEJBException {
+        deploy((CoreDeploymentInfo)deploymentInfo);
     }
 
-    private synchronized void deploy(Object deploymentId, CoreDeploymentInfo deploymentInfo) {
+    public void undeploy(DeploymentInfo info) throws OpenEJBException {
+        undeploy((CoreDeploymentInfo)info);
+    }
+
+    private synchronized void undeploy(CoreDeploymentInfo deploymentInfo) {
+        deploymentsById.remove(deploymentInfo.getDeploymentID());
+        deploymentInfo.setContainer(null);
+        deploymentInfo.setContainerData(null);
+    }
+    
+    private synchronized void deploy(CoreDeploymentInfo deploymentInfo) {
         Map<Method, MethodType> methods = getLifecycelMethodsOfInterface(deploymentInfo);
         deploymentInfo.setContainerData(new Data(new Index<Method,MethodType>(methods)));
 
-        deploymentsById.put(deploymentId, deploymentInfo);
+        deploymentsById.put(deploymentInfo.getDeploymentID(), deploymentInfo);
         deploymentInfo.setContainer(this);
     }
 
     public Object invoke(Object deployID, Method callMethod, Object [] args, Object primKey, Object securityIdentity) throws OpenEJBException {
         CoreDeploymentInfo deployInfo = (CoreDeploymentInfo) this.getDeploymentInfo(deployID);
+        if (deployInfo == null) throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='"+deployID+"'), Container(id='"+containerID+"')");
 
         Data data = (Data) deployInfo.getContainerData();
         MethodType methodType = data.getMethodIndex().get(callMethod);

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?view=diff&rev=500168&r1=500167&r2=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java Thu Jan 25 23:38:56 2007
@@ -79,16 +79,28 @@
         return containerID;
     }
 
-    public void deploy(Object deploymentID, DeploymentInfo info) throws OpenEJBException {
+    public void deploy(DeploymentInfo info) throws OpenEJBException {
         HashMap registry = (HashMap) deploymentRegistry.clone();
-        registry.put(deploymentID, info);
+        registry.put(info.getDeploymentID(), info);
         deploymentRegistry = registry;
         org.apache.openejb.core.CoreDeploymentInfo di = (org.apache.openejb.core.CoreDeploymentInfo) info;
         di.setContainer(this);
     }
 
+    public void undeploy(DeploymentInfo info) throws OpenEJBException {
+        undeploy((CoreDeploymentInfo)info);
+    }
+
+    private synchronized void undeploy(CoreDeploymentInfo deploymentInfo) {
+        deploymentRegistry.remove(deploymentInfo.getDeploymentID());
+        deploymentInfo.setContainer(null);
+        deploymentInfo.setContainerData(null);
+    }
+
     public Object invoke(Object deployID, Method callMethod, Object [] args, Object primKey, Object securityIdentity) throws OpenEJBException {
         CoreDeploymentInfo deployInfo = (CoreDeploymentInfo) this.getDeploymentInfo(deployID);
+        if (deployInfo == null) throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='"+deployID+"'), Container(id='"+containerID+"')");
+        
         ThreadContext callContext = new ThreadContext(deployInfo, primKey, securityIdentity);
         ThreadContext oldCallContext = ThreadContext.enter(callContext);
         try {

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java?view=auto&rev=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java Thu Jan 25 23:38:56 2007
@@ -0,0 +1,91 @@
+/**
+ * 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.assembler.classic;
+
+import junit.framework.TestCase;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.client.LocalInitialContextFactory;
+import org.apache.openejb.test.stateful.AnnotatedFieldInjectionStatefulBean;
+import org.apache.openejb.test.stateless.EncStatelessHome;
+import org.apache.openejb.test.stateless.EncStatelessObject;
+import org.apache.openejb.test.TestFailureException;
+
+import javax.naming.InitialContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.io.File;
+import java.util.Properties;
+import java.rmi.RemoteException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RedeployTest extends TestCase {
+    public void test() throws Exception {
+        // create reference to openejb itests
+        File file = new File(System.getProperty("user.home") + "/.m2/repository/org/apache/openejb/openejb-itests-beans/3.0-incubating-SNAPSHOT/openejb-itests-beans-3.0-incubating-SNAPSHOT.jar");
+        if (!file.canRead()) return;
+
+        ConfigurationFactory config = new ConfigurationFactory();
+        Assembler assembler = new Assembler();
+
+        assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        assembler.createConnectionManager(config.configureService(ConnectionManagerInfo.class));
+        assembler.createConnector(config.configureService(ConnectorInfo.class));
+
+        assembler.createContainer(config.configureService(BmpEntityContainerInfo.class));
+        assembler.createContainer(config.configureService(CmpEntityContainerInfo.class));
+        assembler.createContainer(config.configureService(StatefulSessionContainerInfo.class));
+        assembler.createContainer(config.configureService(StatelessSessionContainerInfo.class));
+        assembler.createContainer(config.configureService(MdbContainerInfo.class));
+
+        createAndDestroy(assembler, config, file);
+        createAndDestroy(assembler, config, file);
+        createAndDestroy(assembler, config, file);
+    }
+
+    private void createAndDestroy(Assembler assembler, ConfigurationFactory config, File file) throws Exception {
+        assembler.createApplication(config.configureApplication(file));
+
+        Properties properties = new Properties();
+        properties.put(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+        InitialContext ctx = new InitialContext(properties);
+        EncStatelessHome home = (EncStatelessHome) ctx.lookup(AnnotatedFieldInjectionStatefulBean.class.getSimpleName());
+        EncStatelessObject ejbObject = home.create();
+        ejbObject.lookupStringEntry();
+
+        assembler.destroyApplication(file.getAbsolutePath());
+
+        try {
+            ejbObject.lookupStringEntry();
+            fail("Proxy should no longer be valid");
+        } catch (Exception e) {
+            // this should happen
+        }
+
+        try {
+            ctx.lookup(AnnotatedFieldInjectionStatefulBean.class.getSimpleName());
+            fail("JNDI References should have been cleaned up");
+        } catch (NamingException e) {
+            // this also should happen
+        }
+    }
+
+}

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/naming/IvmContextTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/naming/IvmContextTest.java?view=auto&rev=500168
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/naming/IvmContextTest.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/ivm/naming/IvmContextTest.java Thu Jan 25 23:38:56 2007
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.ivm.naming;
+
+import junit.framework.TestCase;
+
+import javax.naming.*;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IvmContextTest extends TestCase {
+    public void test() throws Exception {
+        String str3 = "root/comp/env/rate/work/doc/lot";
+
+        IvmContext context = new IvmContext();
+        context.bind("root/comp/env/rate/work/doc/lot/pop", new Integer(1));
+        context.bind("root/comp/env/rate/work/doc/lot/price", new Integer(2));
+        context.bind("root/comp/env/rate/work/doc/lot/break/story", new Integer(3));
+
+        Object o = context.lookup("comp/env/rate/work/doc/lot/pop");
+        assertNotNull(o);
+        assertTrue(o instanceof Integer);
+        assertEquals(o, new Integer(1));
+
+        context.unbind("root/comp/env/rate/work/doc/lot/pop");
+
+        try {
+            context.lookup("comp/env/rate/work/doc/lot/pop");
+            fail("name should be unbound");
+        } catch (javax.naming.NameNotFoundException e) {
+            // pass
+        }
+
+    }
+}