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 2008/08/16 07:00:55 UTC

svn commit: r686450 - in /openejb/trunk/openejb3/container: openejb-core/src/main/java/org/apache/openejb/ openejb-core/src/main/java/org/apache/openejb/assembler/classic/ openejb-core/src/main/java/org/apache/openejb/client/ openejb-core/src/main/java...

Author: dblevins
Date: Fri Aug 15 22:00:54 2008
New Revision: 686450

URL: http://svn.apache.org/viewvc?rev=686450&view=rev
Log:
OPENEJB-894: InitialContext.close() to shutdown embedded container

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/TransactionSynchronizationRegistryWrapper.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/RecycleTest.java
Removed:
    openejb/trunk/openejb3/container/openejb-core/src/test/resources/META-INF/application.xml
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/Assembler.java
    openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/SystemInstance.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java?rev=686450&r1=686449&r2=686450&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java Fri Aug 15 22:00:54 2008
@@ -19,7 +19,8 @@
 import java.util.Date;
 import java.util.Properties;
 
-import javax.transaction.TransactionManager;
+import javax.transaction.*;
+import javax.transaction.SystemException;
 
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ApplicationServer;
@@ -46,7 +47,7 @@
     public static TransactionManager getTransactionManager(){
         return SystemInstance.get().getComponent(TransactionManager.class);
     }
-    
+
     public static class Instance {
         private static Messages messages = new Messages("org.apache.openejb.util.resources");
         private final Throwable initialized;
@@ -258,8 +259,15 @@
     }
 
     public static void destroy() {
-        instance = null;
+        Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
+        assembler.destroy();
+
         SystemInstance.get().removeComponent(ContainerSystem.class);
+        SystemInstance.get().removeComponent(Assembler.class);
+        SystemInstance.get().removeComponent(TransactionManager.class);
+        SystemInstance.get().removeComponent(SecurityService.class);
+        SystemInstance.reset();
+        instance = null;
     }
 
     /**

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=686450&r1=686449&r2=686450&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Fri Aug 15 22:00:54 2008
@@ -183,7 +183,7 @@
         SystemInstance system = SystemInstance.get();
 
         system.setComponent(Assembler.class, this);
-        
+
         containerSystem = new CoreContainerSystem();
         system.setComponent(ContainerSystem.class, containerSystem);
 
@@ -225,7 +225,7 @@
 
     public static void installNaming() {
         if (System.getProperty(DUCT_TAPE_PROPERTY) != null) return;
-        
+
         /* Add IntraVM JNDI service /////////////////////*/
         Properties systemProperties = System.getProperties();
         synchronized (systemProperties) {
@@ -436,8 +436,8 @@
 
         logger.info("createApplication.start", appInfo.jarPath);
 
-        // To start out, ensure we don't already have any beans deployed with duplicate IDs.  This 
-        // is a conflict we can't handle. 
+        // To start out, ensure we don't already have any beans deployed with duplicate IDs.  This
+        // is a conflict we can't handle.
         List<String> used = new ArrayList<String>();
         for (EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
             for (EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) {
@@ -657,6 +657,25 @@
         });
     }
 
+    public void destroy() {
+        logger.debug("Undeploying Applications");
+        Assembler assembler = this;
+        for (AppInfo appInfo : assembler.getDeployedApplications()) {
+            try {
+                assembler.destroyApplication(appInfo.jarPath);
+            } catch (UndeployException e) {
+                logger.error("Undeployment failed: " + appInfo.jarPath, e);
+            } catch (NoSuchApplicationException e) {
+            }
+        }
+
+        SystemInstance.get().removeComponent(OpenEjbConfiguration.class);
+        SystemInstance.get().removeComponent(JtaEntityManagerRegistry.class);
+        SystemInstance.get().removeComponent(TransactionSynchronizationRegistry.class);
+        SystemInstance.get().removeComponent(EjbResolver.class);
+        SystemInstance.reset();
+    }
+
     public void destroyApplication(String filePath) throws UndeployException, NoSuchApplicationException {
         AppInfo appInfo = deployedApplications.remove(filePath);
         if (appInfo == null) {
@@ -853,7 +872,7 @@
         // MDB container has a resource adapter string name that
         // must be replaced with the real resource adapter instance
         replaceResourceAdapterProperty(serviceRecipe);
-        
+
         Object service = serviceRecipe.create();
 
         logUnusedProperties(serviceRecipe, serviceInfo);

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java?rev=686450&r1=686449&r2=686450&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java Fri Aug 15 22:00:54 2008
@@ -20,6 +20,7 @@
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.core.CoreUserTransaction;
+import org.apache.openejb.core.TransactionSynchronizationRegistryWrapper;
 import org.apache.openejb.core.ivm.naming.CrossClassLoaderJndiReference;
 import org.apache.openejb.core.ivm.naming.IntraVmJndiReference;
 import org.apache.openejb.core.ivm.naming.IvmContext;
@@ -153,8 +154,7 @@
         bindings.put("java:comp/TransactionManager", transactionManager);
 
         // bind TransactionSynchronizationRegistry
-        TransactionSynchronizationRegistry synchronizationRegistry = SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class);
-        bindings.put("java:comp/TransactionSynchronizationRegistry", synchronizationRegistry);
+        bindings.put("java:comp/TransactionSynchronizationRegistry", new TransactionSynchronizationRegistryWrapper());
 
         bindings.put("java:comp/ORB", new SystemComponentReference(ORB.class));
         bindings.put("java:comp/HandleDelegate", new SystemComponentReference(HandleDelegate.class));

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContext.java?rev=686450&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContext.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContext.java Fri Aug 15 22:00:54 2008
@@ -0,0 +1,167 @@
+/**
+ * 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.client;
+
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import java.util.Hashtable;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LocalInitialContext implements Context {
+
+    private static Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, LocalInitialContext.class);
+    private final Context context;
+    private final LocalInitialContextFactory factory;
+
+    public LocalInitialContext(Context context, LocalInitialContextFactory factory) {
+        this.context = context;
+        this.factory = factory;
+    }
+
+    public Object addToEnvironment(String propName, Object propVal) throws NamingException {
+        return context.addToEnvironment(propName, propVal);
+    }
+
+    public void bind(Name name, Object obj) throws NamingException {
+        context.bind(name, obj);
+    }
+
+    public void bind(String name, Object obj) throws NamingException {
+        context.bind(name, obj);
+    }
+
+    public void close() throws NamingException {
+        if (factory.bootedOpenEJB()){
+            logger.info("Destroying container system");
+            factory.close();
+            context.close();
+            OpenEJB.destroy();
+        }
+    }
+
+    public Name composeName(Name name, Name prefix) throws NamingException {
+        return context.composeName(name, prefix);
+    }
+
+    public String composeName(String name, String prefix) throws NamingException {
+        return context.composeName(name, prefix);
+    }
+
+    public Context createSubcontext(Name name) throws NamingException {
+        return context.createSubcontext(name);
+    }
+
+    public Context createSubcontext(String name) throws NamingException {
+        return context.createSubcontext(name);
+    }
+
+    public void destroySubcontext(Name name) throws NamingException {
+        context.destroySubcontext(name);
+    }
+
+    public void destroySubcontext(String name) throws NamingException {
+        context.destroySubcontext(name);
+    }
+
+    public Hashtable<?, ?> getEnvironment() throws NamingException {
+        return context.getEnvironment();
+    }
+
+    public String getNameInNamespace() throws NamingException {
+        return context.getNameInNamespace();
+    }
+
+    public NameParser getNameParser(Name name) throws NamingException {
+        return context.getNameParser(name);
+    }
+
+    public NameParser getNameParser(String name) throws NamingException {
+        return context.getNameParser(name);
+    }
+
+    public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
+        return context.list(name);
+    }
+
+    public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
+        return context.list(name);
+    }
+
+    public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
+        return context.listBindings(name);
+    }
+
+    public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
+        return context.listBindings(name);
+    }
+
+    public Object lookup(Name name) throws NamingException {
+        return context.lookup(name);
+    }
+
+    public Object lookup(String name) throws NamingException {
+        return context.lookup(name);
+    }
+
+    public Object lookupLink(Name name) throws NamingException {
+        return context.lookupLink(name);
+    }
+
+    public Object lookupLink(String name) throws NamingException {
+        return context.lookupLink(name);
+    }
+
+    public void rebind(Name name, Object obj) throws NamingException {
+        context.rebind(name, obj);
+    }
+
+    public void rebind(String name, Object obj) throws NamingException {
+        context.rebind(name, obj);
+    }
+
+    public Object removeFromEnvironment(String propName) throws NamingException {
+        return context.removeFromEnvironment(propName);
+    }
+
+    public void rename(Name oldName, Name newName) throws NamingException {
+        context.rename(oldName, newName);
+    }
+
+    public void rename(String oldName, String newName) throws NamingException {
+        context.rename(oldName, newName);
+    }
+
+    public void unbind(Name name) throws NamingException {
+        context.unbind(name);
+    }
+
+    public void unbind(String name) throws NamingException {
+        context.unbind(name);
+    }
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java?rev=686450&r1=686449&r2=686450&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/client/LocalInitialContextFactory.java Fri Aug 15 22:00:54 2008
@@ -23,10 +23,11 @@
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.naming.spi.InitialContextFactory;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
 import java.util.Hashtable;
 import java.util.Properties;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 
 /**
  * @version $Rev$ $Date$
@@ -36,9 +37,12 @@
     private static OpenEJBInstance openejb;
     private static final String OPENEJB_EMBEDDED_REMOTABLE = "openejb.embedded.remotable";
 
+    private boolean bootedOpenEJB;
+    private Object serviceManager;
+
     public Context getInitialContext(Hashtable env) throws javax.naming.NamingException {
         init(env);
-        return getIntraVmContext(env);
+        return getLocalInitialContext(env);
     }
 
     private void init(Hashtable env) throws javax.naming.NamingException {
@@ -53,19 +57,36 @@
             throw (NamingException) new NamingException("Attempted to load OpenEJB. " + e.getMessage()).initCause(e);
         }
     }
-    
+
+    boolean bootedOpenEJB() {
+        return bootedOpenEJB;
+    }
+
     public void init(Properties properties) throws Exception {
         if (openejb != null) return;
         openejb = new OpenEJBInstance();
         if (openejb.isInitialized()) return;
+        bootedOpenEJB = true;
         SystemInstance.init(properties);
         SystemInstance.get().setProperty("openejb.embedded", "true");
         openejb.init(properties);
-        if (properties.getProperty(OPENEJB_EMBEDDED_REMOTABLE, "false").equalsIgnoreCase("true")){
+        if (properties.getProperty(OPENEJB_EMBEDDED_REMOTABLE, "false").equalsIgnoreCase("true")) {
             bootServerServices();
         }
     }
 
+    public void close(){
+        openejb = null;
+        if (serviceManager != null){
+            try {
+                Method stop = serviceManager.getClass().getMethod("stop");
+                stop.invoke(serviceManager);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     private void bootServerServices() {
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 
@@ -74,37 +95,37 @@
             Method init = serviceManagerClass.getMethod("init");
             Method start = serviceManagerClass.getMethod("start", boolean.class);
 
-            Object serviceManager = serviceManagerClass.newInstance();
+            serviceManager = serviceManagerClass.newInstance();
             try {
                 init.invoke(serviceManager);
             } catch (InvocationTargetException e) {
                 Throwable cause = e.getCause();
-                String msg = "Option Enabled '"+OPENEJB_EMBEDDED_REMOTABLE+"'.  Error, unable to initialize ServiceManager.  Cause: "+cause.getClass().getName()+": "+cause.getMessage();
+                String msg = "Option Enabled '" + OPENEJB_EMBEDDED_REMOTABLE + "'.  Error, unable to initialize ServiceManager.  Cause: " + cause.getClass().getName() + ": " + cause.getMessage();
                 throw new IllegalStateException(msg, cause);
             }
             try {
                 start.invoke(serviceManager, false);
             } catch (InvocationTargetException e) {
                 Throwable cause = e.getCause();
-                String msg = "Option Enabled '"+OPENEJB_EMBEDDED_REMOTABLE+"'.  Error, unable to start ServiceManager.  Cause: "+cause.getClass().getName()+": "+cause.getMessage();
+                String msg = "Option Enabled '" + OPENEJB_EMBEDDED_REMOTABLE + "'.  Error, unable to start ServiceManager.  Cause: " + cause.getClass().getName() + ": " + cause.getMessage();
                 throw new IllegalStateException(msg, cause);
             }
         } catch (ClassNotFoundException e) {
-            String msg = "Enabling option '"+OPENEJB_EMBEDDED_REMOTABLE+"' requires class 'org.apache.openejb.server.ServiceManager' to be available.  Make sure you have the openejb-server-*.jar in your classpath and at least one protocol implementation such as openejb-ejbd-*.jar.";
+            String msg = "Enabling option '" + OPENEJB_EMBEDDED_REMOTABLE + "' requires class 'org.apache.openejb.server.ServiceManager' to be available.  Make sure you have the openejb-server-*.jar in your classpath and at least one protocol implementation such as openejb-ejbd-*.jar.";
             throw new IllegalStateException(msg, e);
         } catch (NoSuchMethodException e) {
-            String msg = "Option Enabled '"+OPENEJB_EMBEDDED_REMOTABLE+"'.  Error, 'init' and 'start' methods not found on as expected on class 'org.apache.openejb.server.ServiceManager'.  This should never happen.";
+            String msg = "Option Enabled '" + OPENEJB_EMBEDDED_REMOTABLE + "'.  Error, 'init' and 'start' methods not found on as expected on class 'org.apache.openejb.server.ServiceManager'.  This should never happen.";
             throw new IllegalStateException(msg, e);
         } catch (InstantiationException e) {
-            String msg = "Option Enabled '"+OPENEJB_EMBEDDED_REMOTABLE+"'.  Error, unable to instantiate ServiceManager class 'org.apache.openejb.server.ServiceManager'.";
+            String msg = "Option Enabled '" + OPENEJB_EMBEDDED_REMOTABLE + "'.  Error, unable to instantiate ServiceManager class 'org.apache.openejb.server.ServiceManager'.";
             throw new IllegalStateException(msg, e);
         } catch (IllegalAccessException e) {
-            String msg = "Option Enabled '"+OPENEJB_EMBEDDED_REMOTABLE+"'.  Error, 'init' and 'start' methods cannot be accessed on class 'org.apache.openejb.server.ServiceManager'.  The VM SecurityManager settings must be adjusted.";
+            String msg = "Option Enabled '" + OPENEJB_EMBEDDED_REMOTABLE + "'.  Error, 'init' and 'start' methods cannot be accessed on class 'org.apache.openejb.server.ServiceManager'.  The VM SecurityManager settings must be adjusted.";
             throw new IllegalStateException(msg, e);
         }
     }
 
-    private Context getIntraVmContext(Hashtable env) throws javax.naming.NamingException {
+    private Context getLocalInitialContext(Hashtable env) throws javax.naming.NamingException {
         Context context = null;
         try {
             InitialContextFactory factory = null;
@@ -113,11 +134,16 @@
 
             factory = (InitialContextFactory) ivmFactoryClass.newInstance();
             context = factory.getInitialContext(env);
+
+            Class clientWrapper = Class.forName("org.apache.openejb.client.LocalInitialContext", true, cl);
+            Constructor constructor = clientWrapper.getConstructor(Context.class, this.getClass());
+            context = (Context) constructor.newInstance(context, this);
         } catch (Exception e) {
-            throw (NamingException)new javax.naming.NamingException("Cannot instantiate an IntraVM InitialContext. Exception: "
+            throw (NamingException) new javax.naming.NamingException("Cannot instantiate a LocalInitialContext. Exception: "
                     + e.getClass().getName() + " " + e.getMessage()).initCause(e);
         }
 
         return context;
     }
+
 }
\ No newline at end of file

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/TransactionSynchronizationRegistryWrapper.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/TransactionSynchronizationRegistryWrapper.java?rev=686450&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/TransactionSynchronizationRegistryWrapper.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/TransactionSynchronizationRegistryWrapper.java Fri Aug 15 22:00:54 2008
@@ -0,0 +1,73 @@
+/**
+ * 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;
+
+import org.apache.openejb.loader.SystemInstance;
+
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.Synchronization;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TransactionSynchronizationRegistryWrapper implements TransactionSynchronizationRegistry {
+    private SystemInstance system;
+    private TransactionSynchronizationRegistry registry;
+
+    public TransactionSynchronizationRegistryWrapper() {
+        SystemInstance system = SystemInstance.get();
+        this.registry = system.getComponent(TransactionSynchronizationRegistry.class);
+        this.system = system;
+    }
+
+    public TransactionSynchronizationRegistry getRegistry() {
+        SystemInstance system = SystemInstance.get();
+        if (system != this.system){
+            this.registry = system.getComponent(TransactionSynchronizationRegistry.class);
+            this.system = system;
+        }
+        return registry;
+    }
+
+    public Object getResource(Object o) {
+        return getRegistry().getResource(o);
+    }
+
+    public boolean getRollbackOnly() {
+        return getRegistry().getRollbackOnly();
+    }
+
+    public Object getTransactionKey() {
+        return getRegistry().getTransactionKey();
+    }
+
+    public int getTransactionStatus() {
+        return getRegistry().getTransactionStatus();
+    }
+
+    public void putResource(Object o, Object o1) {
+        getRegistry().putResource(o, o1);
+    }
+
+    public void registerInterposedSynchronization(Synchronization synchronization) {
+        getRegistry().registerInterposedSynchronization(synchronization);
+    }
+
+    public void setRollbackOnly() {
+        getRegistry().setRollbackOnly();
+    }
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/Assembler.java?rev=686450&r1=686449&r2=686450&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/Assembler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/Assembler.java Fri Aug 15 22:00:54 2008
@@ -34,4 +34,5 @@
 
     public SecurityService getSecurityService();
 
+    public void destroy();
 }
\ No newline at end of file

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/RecycleTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/RecycleTest.java?rev=686450&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/RecycleTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/RecycleTest.java Fri Aug 15 22:00:54 2008
@@ -0,0 +1,46 @@
+/**
+ * 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 junit.framework.TestCase;
+
+import javax.naming.InitialContext;
+import javax.naming.Context;
+import java.util.Properties;
+
+import org.apache.openejb.client.LocalInitialContextFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RecycleTest extends TestCase {
+
+    public void test() throws Exception {
+        Properties props = new Properties();
+        props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+        InitialContext context = new InitialContext(props);
+
+        context.close();
+
+
+        context = new InitialContext(props);
+
+        context.close();
+
+    }
+
+}

Modified: openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/SystemInstance.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/SystemInstance.java?rev=686450&r1=686449&r2=686450&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/SystemInstance.java (original)
+++ openejb/trunk/openejb3/container/openejb-loader/src/main/java/org/apache/openejb/loader/SystemInstance.java Fri Aug 15 22:00:54 2008
@@ -151,11 +151,7 @@
     private static SystemInstance system;
 
     static {
-        try {
-            system = new SystemInstance(System.getProperties());
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to create default instance of SystemInstance", e);
-        }
+        reset();
     }
 
     private static boolean initialized;
@@ -164,6 +160,15 @@
         return initialized;
     }
 
+    public static void reset(){
+        try {
+            system = new SystemInstance(System.getProperties());
+            initialized = false;
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to create default instance of SystemInstance", e);
+        }
+    }
+
     public static void init(Properties properties) throws Exception {
         if (initialized) return;
         system = new SystemInstance(properties);