You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by an...@apache.org on 2016/02/19 17:13:19 UTC

[5/5] tomee git commit: Fix rare race condition in OpenEjbContainer

Fix rare race condition in OpenEjbContainer

This was a mix of the runtime, shutdownhook, & finalizer all calling
close on the unsychronized container methods.


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d68ba480
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d68ba480
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d68ba480

Branch: refs/heads/tomee-1.7.x
Commit: d68ba480d132c74d5c1b086e7feb4b40413c2786
Parents: 7341e10
Author: AndyGee <an...@gmx.de>
Authored: Fri Feb 19 17:02:42 2016 +0100
Committer: AndyGee <an...@gmx.de>
Committed: Fri Feb 19 17:02:42 2016 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/openejb/OpenEJB.java   |  79 +++--
 .../org/apache/openejb/OpenEjbContainer.java    | 334 +++++++++++--------
 .../openejb/core/LocalInitialContext.java       |   6 +-
 .../org/superbiz/injection/secure/Movies.java   |   9 +-
 .../superbiz/injection/secure/MovieTest.java    |  40 ++-
 .../apache/tomee/RemoteTomEEEJBContainer.java   | 156 +++++----
 .../tomee/embedded/EmbeddedTomEEContainer.java  | 238 +++++++------
 7 files changed, 480 insertions(+), 382 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java b/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
index a37ed38..b0cc192 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/OpenEJB.java
@@ -103,8 +103,8 @@ public final class OpenEJB {
 
             final Logger logger2 = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
             final String[] bannerValues = new String[]{
-                null, versionInfo.getUrl(), new Date().toString(), versionInfo.getCopyright(),
-                versionInfo.getVersion(), versionInfo.getDate(), versionInfo.getTime(), null
+                    null, versionInfo.getUrl(), new Date().toString(), versionInfo.getCopyright(),
+                    versionInfo.getVersion(), versionInfo.getDate(), versionInfo.getTime(), null
             };
             for (int i = 0; i < bannerValues.length; i++) {
                 if (bannerValues[i] == null) {
@@ -173,9 +173,9 @@ public final class OpenEJB {
                 if (containerSystem.containers().length > 0) {
                     final Container[] c = containerSystem.containers();
                     logger.debug("startup.debugContainersType");
-                    for (int i = 0; i < c.length; i++) {
+                    for (final Container aC : c) {
                         String entry = "   ";
-                        switch (c[i].getContainerType()) {
+                        switch (aC.getContainerType()) {
                             case BMP_ENTITY:
                                 entry += "BMP ENTITY  ";
                                 break;
@@ -191,43 +191,48 @@ public final class OpenEJB {
                             case MESSAGE_DRIVEN:
                                 entry += "MESSAGE     ";
                                 break;
+                            case SINGLETON:
+                                entry += "SINGLETON     ";
+                                break;
                         }
-                        entry += c[i].getContainerID();
+                        entry += aC.getContainerID();
                         logger.debug("startup.debugEntry", entry);
                     }
                 }
 
-                logger.debug("startup.debugDeployments", containerSystem.deployments().length);
-                if (containerSystem.deployments().length > 0) {
-                    logger.debug("startup.debugDeploymentsType");
-                    final BeanContext[] d = containerSystem.deployments();
-                    for (int i = 0; i < d.length; i++) {
-                        String entry = "   ";
-                        switch (d[i].getComponentType()) {
-                            case BMP_ENTITY:
-                                entry += "BMP_ENTITY  ";
-                                break;
-                            case CMP_ENTITY:
-                                entry += "CMP_ENTITY  ";
-                                break;
-                            case STATEFUL:
-                                entry += "STATEFUL    ";
-                                break;
-                            case MANAGED:
-                                entry += "MANAGED     ";
-                                break;
-                            case STATELESS:
-                                entry += "STATELESS   ";
-                                break;
-                            case SINGLETON:
-                                entry += "SINGLETON   ";
-                                break;
-                            case MESSAGE_DRIVEN:
-                                entry += "MESSAGE     ";
-                                break;
+                if (logger.isDebugEnabled()) {
+                    logger.debug("startup.debugDeployments", containerSystem.deployments().length);
+                    if (containerSystem.deployments().length > 0) {
+                        logger.debug("startup.debugDeploymentsType");
+                        final BeanContext[] d = containerSystem.deployments();
+                        for (final BeanContext aD : d) {
+                            String entry = "   ";
+                            switch (aD.getComponentType()) {
+                                case BMP_ENTITY:
+                                    entry += "BMP_ENTITY  ";
+                                    break;
+                                case CMP_ENTITY:
+                                    entry += "CMP_ENTITY  ";
+                                    break;
+                                case STATEFUL:
+                                    entry += "STATEFUL    ";
+                                    break;
+                                case MANAGED:
+                                    entry += "MANAGED     ";
+                                    break;
+                                case STATELESS:
+                                    entry += "STATELESS   ";
+                                    break;
+                                case SINGLETON:
+                                    entry += "SINGLETON   ";
+                                    break;
+                                case MESSAGE_DRIVEN:
+                                    entry += "MESSAGE     ";
+                                    break;
+                            }
+                            entry += aD.getDeploymentID();
+                            logger.debug("startup.debugEntry", entry);
                         }
-                        entry += d[i].getDeploymentID();
-                        logger.debug("startup.debugEntry", entry);
                     }
                 }
             }
@@ -261,7 +266,7 @@ public final class OpenEJB {
         }
     }
 
-    public static void destroy() {
+    public static synchronized void destroy() {
 
         final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
 
@@ -289,7 +294,7 @@ public final class OpenEJB {
     /**
      * 2 usages
      */
-    public static void init(final Properties initProps, final ApplicationServer appServer) throws OpenEJBException {
+    public static synchronized void init(final Properties initProps, final ApplicationServer appServer) throws OpenEJBException {
         if (isInitialized()) {
             if (instance != null) {
                 final String msg = messages.message("startup.alreadyInitialized");

http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
index 803b6cf..f958728 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/OpenEjbContainer.java
@@ -79,6 +79,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.LogManager;
 
 import static org.apache.openejb.cdi.ScopeHelper.startContexts;
@@ -88,6 +89,7 @@ import static org.apache.openejb.cdi.ScopeHelper.stopContexts;
  * @version $Rev$ $Date$
  */
 public final class OpenEjbContainer extends EJBContainer {
+
     static {
         // if tomee embedded was ran we'll lost log otherwise
         final String logManger = System.getProperty("java.util.logging.manager");
@@ -107,11 +109,16 @@ public final class OpenEjbContainer extends EJBContainer {
         }
     }
 
+    /**
+     * Used to synchronize the container create and close methods
+     */
+    private static final ReentrantLock LOCK = new ReentrantLock();
+
     public static final String OPENEJB_EMBEDDED_REMOTABLE = "openejb.embedded.remotable";
     public static final String OPENEJB_EJBCONTAINER_CLOSE = "openejb.ejbcontainer.close";
     public static final String OPENEJB_EJBCONTAINER_CLOSE_SINGLE = "single-jvm";
 
-    private static OpenEjbContainer instance;
+    private static volatile OpenEjbContainer instance;
     private static Logger logger; // initialized lazily to get the logging config from properties
 
     private ServiceManagerProxy serviceManager;
@@ -144,7 +151,9 @@ public final class OpenEjbContainer extends EJBContainer {
     @Override
     protected void finalize() throws Throwable {
         try {
-            this.close();
+            if(this.equals(instance)) {
+                this.close();
+            }
         } catch (final Exception e) {
             //no-op
         } finally {
@@ -152,52 +161,57 @@ public final class OpenEjbContainer extends EJBContainer {
         }
     }
 
-    @Override
-    public void close() {
-        if (isSingleClose()) {
-            return;
-        }
-        doClose();
-    }
-
     private static boolean isSingleClose() {
         return OPENEJB_EJBCONTAINER_CLOSE_SINGLE.equals(SystemInstance.get().getProperty(OPENEJB_EJBCONTAINER_CLOSE, "by-invocation"));
     }
 
-    private synchronized void doClose() {
-        if (instance == null) {
-            return;
-        }
+    private void doClose() {
+
+        final ReentrantLock lock = LOCK;
+        lock.lock();
 
-        if (serviceManager != null) {
-            serviceManager.stop();
+        final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+        for (final StackTraceElement element : stackTrace) {
+            logger().info("Called by: " + element);
         }
+
         try {
-            globalJndiContext.close();
-        } catch (final NamingException e) {
-            throw new IllegalStateException(e);
-        }
+            if (instance == null) {
+                return;
+            }
 
-        final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
-        if (assembler != null) {
-            for (final AppInfo info : assembler.getDeployedApplications()) {
-                try {
-                    assembler.destroyApplication(info);
-                } catch (final UndeployException e) {
-                    logger().error(e.getMessage(), e);
+            if (serviceManager != null) {
+                serviceManager.stop();
+            }
+            try {
+                globalJndiContext.close();
+            } catch (final NamingException e) {
+                throw new IllegalStateException(e);
+            }
+
+            final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
+            if (assembler != null) {
+                for (final AppInfo info : assembler.getDeployedApplications()) {
+                    try {
+                        assembler.destroyApplication(info);
+                    } catch (final UndeployException e) {
+                        logger().error(e.getMessage(), e);
+                    }
                 }
             }
-        }
 
-        try {
-            stopContexts(webBeanContext.getContextsService(), servletContext, session);
-        } catch (final Exception e) {
-            logger().warning("can't stop all CDI contexts", e);
-        }
+            try {
+                stopContexts(webBeanContext.getContextsService(), servletContext, session);
+            } catch (final Exception e) {
+                logger().warning("can't stop all CDI contexts", e);
+            }
 
-        logger().info("Destroying OpenEJB container");
-        OpenEJB.destroy();
-        instance = null;
+            logger().info("Destroying OpenEJB container");
+            OpenEJB.destroy();
+            instance = null;
+        } finally {
+            lock.unlock();
+        }
     }
 
     @Override
@@ -226,174 +240,198 @@ public final class OpenEjbContainer extends EJBContainer {
         return logger;
     }
 
+    @Override
+    public void close() {
+
+        final ReentrantLock lock = LOCK;
+        lock.lock();
+
+        try {
+            if (isSingleClose()) {
+                return;
+            }
+            doClose();
+        } finally {
+            lock.unlock();
+        }
+    }
+
     public static class Provider implements EJBContainerProvider {
         public static final String OPENEJB_ADDITIONNAL_CALLERS_KEY = "openejb.additionnal.callers";
 
         @Override
         public EJBContainer createEJBContainer(Map<?, ?> map) {
-            if (map == null) { // JBoss EJB API pass null when calling EJBContainer.createEJBContainer()
-                map = new HashMap<Object, Object>();
-            }
 
-            if (isOtherProvider(map)) {
-                return null;
-            }
+            final ReentrantLock lock = LOCK;
+            lock.lock();
 
-            if (instance != null || OpenEJB.isInitialized()) {
-                if (!isSingleClose()) {
-                    logger().info("EJBContainer already initialized.  Call ejbContainer.close() to allow reinitialization");
+            try {
+                if (map == null) { // JBoss EJB API pass null when calling EJBContainer.createEJBContainer()
+                    map = new HashMap<Object, Object>();
                 }
-                return instance;
-            }
-
 
-            try {
-                // reset to be able to run this container then tomee one etc...
-                if (System.getProperties().containsKey(Context.URL_PKG_PREFIXES)) {
-                    System.getProperties().remove(Context.URL_PKG_PREFIXES);
+                if (isOtherProvider(map)) {
+                    return null;
                 }
 
-                final Properties properties = new Properties();
-                properties.putAll(map);
+                if (instance != null || OpenEJB.isInitialized()) {
+                    if (!isSingleClose()) {
+                        logger().info("EJBContainer already initialized.  Call ejbContainer.close() to allow reinitialization");
+                    }
+                    return instance;
+                }
 
-                SystemInstance.reset();
-                SystemInstance.init(properties);
-                SystemInstance.get().setProperty("openejb.embedded", "true");
-                SystemInstance.get().setProperty(EJBContainer.class.getName(), "true");
 
-                if (SystemInstance.get().getComponent(ParentClassLoaderFinder.class) == null) {
-                    ClassLoader tccl = Thread.currentThread().getContextClassLoader();
-                    if (tccl == null) {
-                        tccl = OpenEjbContainer.class.getClassLoader();
+                try {
+                    // reset to be able to run this container then tomee one etc...
+                    if (System.getProperties().containsKey(Context.URL_PKG_PREFIXES)) {
+                        System.getProperties().remove(Context.URL_PKG_PREFIXES);
                     }
-                    SystemInstance.get().setComponent(ParentClassLoaderFinder.class, new ProvidedClassLoaderFinder(tccl));
-                }
 
-                OptionsLog.install();
+                    final Properties properties = new Properties();
+                    properties.putAll(map);
 
-                OpenEJB.init(properties);
+                    SystemInstance.reset();
+                    SystemInstance.init(properties);
+                    SystemInstance.get().setProperty("openejb.embedded", "true");
+                    SystemInstance.get().setProperty(EJBContainer.class.getName(), "true");
 
-                Core.warmup(); // don't do it too eagerly to avoid to not have properties
+                    if (SystemInstance.get().getComponent(ParentClassLoaderFinder.class) == null) {
+                        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+                        if (tccl == null) {
+                            tccl = OpenEjbContainer.class.getClassLoader();
+                        }
+                        SystemInstance.get().setComponent(ParentClassLoaderFinder.class, new ProvidedClassLoaderFinder(tccl));
+                    }
 
-                DeploymentLoader.reloadAltDD(); // otherwise hard to use multiple altdd with several start/stop in the same JVM
+                    OptionsLog.install();
 
-                final ConfigurationFactory configurationFactory = new ConfigurationFactory();
+                    OpenEJB.init(properties);
 
+                    Core.warmup(); // don't do it too eagerly to avoid to not have properties
 
-                final AppModule appModule = load(map, configurationFactory);
+                    DeploymentLoader.reloadAltDD(); // otherwise hard to use multiple altdd with several start/stop in the same JVM
 
-                final Set<String> callers;
-                if (map.containsKey(OPENEJB_ADDITIONNAL_CALLERS_KEY)) {
-                    callers = new LinkedHashSet<String>();
-                    callers.addAll(Arrays.asList(((String) map.get(OPENEJB_ADDITIONNAL_CALLERS_KEY)).split(",")));
-                } else {
-                    callers = NewLoaderLogic.callers();
-                }
+                    final ConfigurationFactory configurationFactory = new ConfigurationFactory();
 
-                final EjbJar ejbJar = new EjbJar();
-                final OpenejbJar openejbJar = new OpenejbJar();
 
-                for (final String caller : callers) {
+                    final AppModule appModule = load(map, configurationFactory);
 
-                    if (!isValid(caller)) {
-                        continue;
+                    final Set<String> callers;
+                    if (map.containsKey(OPENEJB_ADDITIONNAL_CALLERS_KEY)) {
+                        callers = new LinkedHashSet<String>();
+                        callers.addAll(Arrays.asList(((String) map.get(OPENEJB_ADDITIONNAL_CALLERS_KEY)).split(",")));
+                    } else {
+                        callers = NewLoaderLogic.callers();
                     }
 
-                    String name = caller;
-                    if (name.contains("$")) {
-                        name = caller.replace("$", "_");
-                    }
+                    final EjbJar ejbJar = new EjbJar();
+                    final OpenejbJar openejbJar = new OpenejbJar();
 
-                    final ManagedBean bean = ejbJar.addEnterpriseBean(new ManagedBean(name, caller, true));
-                    bean.localBean();
+                    for (final String caller : callers) {
 
-                    // set it to bean so it can get UserTransaction injection
-                    bean.setTransactionType(TransactionType.BEAN);
+                        if (!isValid(caller)) {
+                            continue;
+                        }
 
-                    final EjbDeployment ejbDeployment = openejbJar.addEjbDeployment(bean);
+                        String name = caller;
+                        if (name.contains("$")) {
+                            name = caller.replace("$", "_");
+                        }
 
-                    // important in case any other deploment id formats are specified
-                    ejbDeployment.setDeploymentId(name);
-                }
+                        final ManagedBean bean = ejbJar.addEnterpriseBean(new ManagedBean(name, caller, true));
+                        bean.localBean();
 
-                appModule.getEjbModules().add(new EjbModule(ejbJar, openejbJar));
+                        // set it to bean so it can get UserTransaction injection
+                        bean.setTransactionType(TransactionType.BEAN);
 
+                        final EjbDeployment ejbDeployment = openejbJar.addEjbDeployment(bean);
 
-                final AppInfo appInfo;
-                try {
+                        // important in case any other deploment id formats are specified
+                        ejbDeployment.setDeploymentId(name);
+                    }
 
-                    appInfo = configurationFactory.configureApplication(appModule);
+                    appModule.getEjbModules().add(new EjbModule(ejbJar, openejbJar));
 
-                } catch (final ValidationFailedException e) {
 
-                    logger().warning("configureApplication.loadFailed", appModule.getModuleId(), e.getMessage()); // DO not include the stacktrace in the message
+                    final AppInfo appInfo;
+                    try {
 
-                    throw new InvalidApplicationException(e);
+                        appInfo = configurationFactory.configureApplication(appModule);
 
-                } catch (final OpenEJBException e) {
-                    // DO NOT REMOVE THE EXCEPTION FROM THIS LOG MESSAGE
-                    // removing this message causes NO messages to be printed when embedded
-                    logger().warning("configureApplication.loadFailed", e, appModule.getModuleId(), e.getMessage());
+                    } catch (final ValidationFailedException e) {
 
-                    throw new ConfigureApplicationException(e);
-                }
+                        logger().warning("configureApplication.loadFailed", appModule.getModuleId(), e.getMessage()); // DO not include the stacktrace in the message
 
-                final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
+                        throw new InvalidApplicationException(e);
 
-                if(null == assembler){
-                    throw new IllegalStateException("Assembler has not been initialized");
-                }
+                    } catch (final OpenEJBException e) {
+                        // DO NOT REMOVE THE EXCEPTION FROM THIS LOG MESSAGE
+                        // removing this message causes NO messages to be printed when embedded
+                        logger().warning("configureApplication.loadFailed", e, appModule.getModuleId(), e.getMessage());
 
-                final AppContext appContext;
+                        throw new ConfigureApplicationException(e);
+                    }
 
-                try {
-                    appContext = assembler.createApplication(appInfo, appModule.getClassLoader());
-                } catch (final ValidationException ve) {
-                    throw ve;
-                } catch (final Exception e) {
-                    throw new AssembleApplicationException(e);
-                }
+                    final Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
+
+                    if (null == assembler) {
+                        throw new IllegalStateException("Assembler has not been initialized");
+                    }
+
+                    final AppContext appContext;
+
+                    try {
+                        appContext = assembler.createApplication(appInfo, appModule.getClassLoader());
+                    } catch (final ValidationException ve) {
+                        throw ve;
+                    } catch (final Exception e) {
+                        throw new AssembleApplicationException(e);
+                    }
 
 
-                final OpenEjbContainer openEjbContainer = instance = new OpenEjbContainer(map, appContext);
-                if (isSingleClose()) {
-                    Runtime.getRuntime().addShutdownHook(new Thread() {
-                        @Override
-                        public void run() {
-                            if (instance != null) {
-                                instance.doClose();
+                    final OpenEjbContainer openEjbContainer = instance = new OpenEjbContainer(map, appContext);
+                    if (isSingleClose()) {
+                        Runtime.getRuntime().addShutdownHook(new Thread() {
+                            @Override
+                            public void run() {
+                                if (instance != null) {
+                                    instance.doClose();
+                                }
                             }
-                        }
-                    });
-                }
-                return openEjbContainer;
+                        });
+                    }
+                    return openEjbContainer;
 
-            } catch (final OpenEJBException e) {
+                } catch (final OpenEJBException e) {
 
-                throw new EJBException(e);
+                    throw new EJBException(e);
 
-            } catch (final MalformedURLException e) {
+                } catch (final MalformedURLException e) {
 
-                throw new EJBException(e);
+                    throw new EJBException(e);
 
-            } catch (final ValidationException ve) {
-                throw ve;
-            } catch (final Exception e) {
+                } catch (final ValidationException ve) {
+                    throw ve;
+                } catch (final Exception e) {
 
-                if (e instanceof EJBException) {
+                    if (e instanceof EJBException) {
 
-                    throw (EJBException) e;
-                }
+                        throw (EJBException) e;
+                    }
 
-                throw new InitializationException(e);
-            } finally {
-                if (instance == null && OpenEJB.isInitialized()) {
-                    try {
-                        OpenEJB.destroy();
-                    } catch (final Exception e) {
-                        // no-op
+                    throw new InitializationException(e);
+                } finally {
+                    if (instance == null && OpenEJB.isInitialized()) {
+                        try {
+                            OpenEJB.destroy();
+                        } catch (final Exception e) {
+                            // no-op
+                        }
                     }
                 }
+            } finally {
+                lock.unlock();
             }
         }
 
@@ -590,7 +628,7 @@ public final class OpenEjbContainer extends EJBContainer {
         private static boolean isOtherProvider(final Map<?, ?> properties) {
             final Object provider = properties.get(EJBContainer.PROVIDER);
             return provider != null && !provider.equals(OpenEjbContainer.class) && !provider.equals(OpenEjbContainer.class.getName())
-                && !"openejb".equals(provider);
+                    && !"openejb".equals(provider);
         }
 
         private boolean match(final String s, final File file) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/container/openejb-core/src/main/java/org/apache/openejb/core/LocalInitialContext.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/LocalInitialContext.java b/container/openejb-core/src/main/java/org/apache/openejb/core/LocalInitialContext.java
index b43570d..64a645c 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/LocalInitialContext.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/LocalInitialContext.java
@@ -141,12 +141,14 @@ public class LocalInitialContext extends ContextWrapper {
     @SuppressWarnings("unchecked")
     private void logout() {
         try {
-            final SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class);
             if (clientIdentity != null) {
                 if (logger.isDebugEnabled()) {
                     logger.debug("Logging out: " + clientIdentity);
                 }
-                securityService.logout(clientIdentity);
+                final SecurityService securityService = SystemInstance.get().getComponent(SecurityService.class);
+                if (null != securityService) {
+                    securityService.logout(clientIdentity);
+                }
                 ClientSecurity.setIdentity(null);
             }
         } catch (final LoginException e) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/examples/testing-security-4/src/main/java/org/superbiz/injection/secure/Movies.java
----------------------------------------------------------------------
diff --git a/examples/testing-security-4/src/main/java/org/superbiz/injection/secure/Movies.java b/examples/testing-security-4/src/main/java/org/superbiz/injection/secure/Movies.java
index b3ba8e8..96d95ff 100644
--- a/examples/testing-security-4/src/main/java/org/superbiz/injection/secure/Movies.java
+++ b/examples/testing-security-4/src/main/java/org/superbiz/injection/secure/Movies.java
@@ -18,6 +18,7 @@ package org.superbiz.injection.secure;
 
 //START SNIPPET: code
 
+import javax.annotation.PreDestroy;
 import javax.annotation.security.PermitAll;
 import javax.annotation.security.RolesAllowed;
 import javax.ejb.Stateful;
@@ -27,6 +28,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.persistence.PersistenceContextType;
 import javax.persistence.Query;
+import javax.persistence.TypedQuery;
 import java.util.List;
 
 @Stateful
@@ -36,20 +38,19 @@ public class Movies {
     private EntityManager entityManager;
 
     @RolesAllowed({"Employee", "Manager"})
-    public void addMovie(Movie movie) throws Exception {
+    public void addMovie(final Movie movie) throws Exception {
         entityManager.persist(movie);
     }
 
     @RolesAllowed({"Manager"})
-    public void deleteMovie(Movie movie) throws Exception {
+    public void deleteMovie(final Movie movie) throws Exception {
         entityManager.remove(movie);
     }
 
     @PermitAll
     @TransactionAttribute(TransactionAttributeType.SUPPORTS)
     public List<Movie> getMovies() throws Exception {
-        Query query = entityManager.createQuery("SELECT m from Movie as m");
-        return query.getResultList();
+        return entityManager.createQuery("SELECT m from Movie as m", Movie.class).getResultList();
     }
 }
 //END SNIPPET: code

http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/examples/testing-security-4/src/test/java/org/superbiz/injection/secure/MovieTest.java
----------------------------------------------------------------------
diff --git a/examples/testing-security-4/src/test/java/org/superbiz/injection/secure/MovieTest.java b/examples/testing-security-4/src/test/java/org/superbiz/injection/secure/MovieTest.java
index 0e3654b..2483e66 100644
--- a/examples/testing-security-4/src/test/java/org/superbiz/injection/secure/MovieTest.java
+++ b/examples/testing-security-4/src/test/java/org/superbiz/injection/secure/MovieTest.java
@@ -21,6 +21,7 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import javax.annotation.PreDestroy;
 import javax.ejb.EJB;
 import javax.ejb.EJBAccessException;
 import javax.ejb.embeddable.EJBContainer;
@@ -36,12 +37,13 @@ public class MovieTest {
     @EJB
     private Movies movies;
 
-    private EJBContainer container;
+    private volatile EJBContainer container;
 
-    private Context getContext(String user, String pass) throws NamingException {
-        Properties p = new Properties();
+    private Context getContext(final String user, final String pass) throws NamingException {
+        final Properties p = new Properties();
         p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory");
         p.setProperty("openejb.authentication.realmName", "ScriptLogin");
+        p.setProperty("openejb.embedded.initialcontext.close", "destroy");
         p.put(Context.SECURITY_PRINCIPAL, user);
         p.put(Context.SECURITY_CREDENTIALS, pass);
 
@@ -49,21 +51,25 @@ public class MovieTest {
     }
 
     @Before
-    public void setUp() throws Exception {
+    public void before() throws Exception {
         final ClassLoader ctxCl = Thread.currentThread().getContextClassLoader();
         System.setProperty("openejb.ScriptLoginModule.scriptURI", ctxCl.getResource("loginscript.js").toExternalForm());
 
-        Properties p = new Properties();
+        final Properties p = new Properties();
         p.put("movieDatabase", "new://Resource?type=DataSource");
         p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
         p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
 
         this.container = EJBContainer.createEJBContainer(p);
-        this.container.getContext().bind("inject", this);
+        try {
+            this.container.getContext().bind("inject", this);
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
     }
 
     @After
-    public void tearDown() {
+    public void after() {
         this.container.close();
     }
 
@@ -76,10 +82,10 @@ public class MovieTest {
             movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
             movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998));
 
-            List<Movie> list = movies.getMovies();
+            final List<Movie> list = movies.getMovies();
             Assert.assertEquals("List.size()", 3, list.size());
 
-            for (Movie movie : list) {
+            for (final Movie movie : list) {
                 movies.deleteMovie(movie);
             }
 
@@ -98,14 +104,14 @@ public class MovieTest {
             movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
             movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998));
 
-            List<Movie> list = movies.getMovies();
+            final List<Movie> list = movies.getMovies();
             Assert.assertEquals("List.size()", 3, list.size());
 
-            for (Movie movie : list) {
+            for (final Movie movie : list) {
                 try {
                     movies.deleteMovie(movie);
                     Assert.fail("Employees should not be allowed to delete");
-                } catch (EJBAccessException e) {
+                } catch (final EJBAccessException e) {
                     // Good, Employees cannot delete things
                 }
             }
@@ -122,21 +128,21 @@ public class MovieTest {
         try {
             movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
             Assert.fail("Unauthenticated users should not be able to add movies");
-        } catch (EJBAccessException e) {
+        } catch (final EJBAccessException e) {
             // Good, guests cannot add things
         }
 
         try {
             movies.deleteMovie(null);
             Assert.fail("Unauthenticated users should not be allowed to delete");
-        } catch (EJBAccessException e) {
+        } catch (final EJBAccessException e) {
             // Good, Unauthenticated users cannot delete things
         }
 
         try {
             // Read access should be allowed
             movies.getMovies();
-        } catch (EJBAccessException e) {
+        } catch (final EJBAccessException e) {
             Assert.fail("Read access should be allowed");
         }
     }
@@ -146,14 +152,14 @@ public class MovieTest {
         try {
             getContext("eddie", "panama");
             Assert.fail("supposed to have a login failure here");
-        } catch (javax.naming.AuthenticationException e) {
+        } catch (final javax.naming.AuthenticationException e) {
             //expected
         }
 
         try {
             getContext("jimmy", "foxylady");
             Assert.fail("supposed to have a login failure here");
-        } catch (javax.naming.AuthenticationException e) {
+        } catch (final javax.naming.AuthenticationException e) {
             //expected
         }
     }

http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/tomee/apache-tomee/src/main/java/org/apache/tomee/RemoteTomEEEJBContainer.java
----------------------------------------------------------------------
diff --git a/tomee/apache-tomee/src/main/java/org/apache/tomee/RemoteTomEEEJBContainer.java b/tomee/apache-tomee/src/main/java/org/apache/tomee/RemoteTomEEEJBContainer.java
index 67f68b1..60b5583 100644
--- a/tomee/apache-tomee/src/main/java/org/apache/tomee/RemoteTomEEEJBContainer.java
+++ b/tomee/apache-tomee/src/main/java/org/apache/tomee/RemoteTomEEEJBContainer.java
@@ -38,8 +38,15 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.concurrent.locks.ReentrantLock;
 
 public class RemoteTomEEEJBContainer extends EJBContainer {
+
+    /**
+     * Used to synchronize the container create and close methods
+     */
+    private static final ReentrantLock LOCK = new ReentrantLock();
+
     private static RemoteTomEEEJBContainer instance;
     private RemoteServer container;
     private InitialContext context;
@@ -57,8 +64,15 @@ public class RemoteTomEEEJBContainer extends EJBContainer {
 
     @Override
     public void close() {
-        instance.container.destroy();
-        instance.container = null;
+        final ReentrantLock lock = LOCK;
+        lock.lock();
+
+        try {
+            instance.container.destroy();
+            instance.container = null;
+        } finally {
+            lock.unlock();
+        }
     }
 
     @Override
@@ -71,83 +85,91 @@ public class RemoteTomEEEJBContainer extends EJBContainer {
 
         @Override
         public EJBContainer createEJBContainer(final Map<?, ?> properties) {
-            final Object provider = properties.get(EJBContainer.PROVIDER);
-            int ejbContainerProviders = 1;
-            try {
-                ejbContainerProviders = ProviderLocator.getServices(EJBContainerProvider.class.getName(), EJBContainer.class, Thread.currentThread().getContextClassLoader()).size();
-            } catch (final Exception e) {
-                // no-op
-            }
-
-            if ((provider == null && ejbContainerProviders > 1)
-                    || (!RemoteTomEEEJBContainer.class.equals(provider)
-                    && !CONTAINER_NAMES.contains(String.valueOf(provider)))) {
-                return null;
-            }
 
-            if (instance != null) {
-                return instance;
-            }
+            final ReentrantLock lock = LOCK;
+            lock.lock();
 
-            final Object modules = properties.get(EJBContainer.MODULES);
+            try {
+                final Object provider = properties.get(EJBContainer.PROVIDER);
+                int ejbContainerProviders = 1;
+                try {
+                    ejbContainerProviders = ProviderLocator.getServices(EJBContainerProvider.class.getName(), EJBContainer.class, Thread.currentThread().getContextClassLoader()).size();
+                } catch (final Exception e) {
+                    // no-op
+                }
 
-            System.getProperties().putAll(properties);
-            final File home = new File(System.getProperty("openejb.home", "doesn't exist"));
-            if (!home.exists()) {
-                throw new IllegalArgumentException("You need to set openejb.home");
-            }
+                if ((provider == null && ejbContainerProviders > 1)
+                        || (!RemoteTomEEEJBContainer.class.equals(provider)
+                        && !CONTAINER_NAMES.contains(String.valueOf(provider)))) {
+                    return null;
+                }
 
-            final QuickServerXmlParser parser = QuickServerXmlParser.parse(new File(home, "conf/server.xml"));
-            final String remoteEjb = System.getProperty(Context.PROVIDER_URL, "http://" + parser.host() + ":" + parser.http() + "/tomee/ejb");
+                if (instance != null) {
+                    return instance;
+                }
 
-            try {
-                instance = new RemoteTomEEEJBContainer();
-                instance.container = new RemoteServer();
-                instance.container.setPortStartup(Integer.parseInt(parser.http()));
+                final Object modules = properties.get(EJBContainer.MODULES);
 
-                try {
-                    instance.container.start();
-                } catch (final Exception e) {
-                    instance.container.destroy();
-                    throw e;
+                System.getProperties().putAll(properties);
+                final File home = new File(System.getProperty("openejb.home", "doesn't exist"));
+                if (!home.exists()) {
+                    throw new IllegalArgumentException("You need to set openejb.home");
                 }
 
-                instance.context = new InitialContext(new Properties() {{
-                    setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
-                    setProperty(Context.PROVIDER_URL, remoteEjb);
-                }});
-
-                final Deployer deployer = Deployer.class.cast(instance.context.lookup("openejb/DeployerBusinessRemote"));
-
-                if (modules instanceof File) {
-                    final File file = File.class.cast(modules);
-                    deployFile(deployer, file);
-                } else if (modules instanceof String) {
-                    final String path = String.class.cast(modules);
-                    final File file = new File(path);
-                    deployFile(deployer, file);
-                } else if (modules instanceof String[]) {
-                    for (final String path : (String[]) modules) {
-                        deployFile(deployer, new File(path));
+                final QuickServerXmlParser parser = QuickServerXmlParser.parse(new File(home, "conf/server.xml"));
+                final String remoteEjb = System.getProperty(Context.PROVIDER_URL, "http://" + parser.host() + ":" + parser.http() + "/tomee/ejb");
+
+                try {
+                    instance = new RemoteTomEEEJBContainer();
+                    instance.container = new RemoteServer();
+                    instance.container.setPortStartup(Integer.parseInt(parser.http()));
+
+                    try {
+                        instance.container.start();
+                    } catch (final Exception e) {
+                        instance.container.destroy();
+                        throw e;
                     }
-                } else if (modules instanceof File[]) {
-                    for (final File file : (File[]) modules) {
+
+                    instance.context = new InitialContext(new Properties() {{
+                        setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
+                        setProperty(Context.PROVIDER_URL, remoteEjb);
+                    }});
+
+                    final Deployer deployer = Deployer.class.cast(instance.context.lookup("openejb/DeployerBusinessRemote"));
+
+                    if (modules instanceof File) {
+                        final File file = File.class.cast(modules);
+                        deployFile(deployer, file);
+                    } else if (modules instanceof String) {
+                        final String path = String.class.cast(modules);
+                        final File file = new File(path);
                         deployFile(deployer, file);
+                    } else if (modules instanceof String[]) {
+                        for (final String path : (String[]) modules) {
+                            deployFile(deployer, new File(path));
+                        }
+                    } else if (modules instanceof File[]) {
+                        for (final File file : (File[]) modules) {
+                            deployFile(deployer, file);
+                        }
+                    } // else suppose already deployed
+
+                    return instance;
+                } catch (final OpenEJBException e) {
+                    throw new EJBException(e);
+                } catch (final MalformedURLException e) {
+                    throw new EJBException(e);
+                } catch (final ValidationException ve) {
+                    throw ve;
+                } catch (final Exception e) {
+                    if (e instanceof EJBException) {
+                        throw (EJBException) e;
                     }
-                } // else suppose already deployed
-
-                return instance;
-            } catch (final OpenEJBException e) {
-                throw new EJBException(e);
-            } catch (final MalformedURLException e) {
-                throw new EJBException(e);
-            } catch (final ValidationException ve) {
-                throw ve;
-            } catch (final Exception e) {
-                if (e instanceof EJBException) {
-                    throw (EJBException) e;
+                    throw new TomEERemoteEJBContainerException("initialization exception", e);
                 }
-                throw new TomEERemoteEJBContainerException("initialization exception", e);
+            } finally {
+                lock.unlock();
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/tomee/blob/d68ba480/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/EmbeddedTomEEContainer.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/EmbeddedTomEEContainer.java b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/EmbeddedTomEEContainer.java
index 964dd5d..7d30a4e 100644
--- a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/EmbeddedTomEEContainer.java
+++ b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/EmbeddedTomEEContainer.java
@@ -5,14 +5,14 @@
  * 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.
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.tomee.embedded;
@@ -39,8 +39,15 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.ReentrantLock;
 
 public final class EmbeddedTomEEContainer extends EJBContainer {
+
+    /**
+     * Used to synchronize the container create and close methods
+     */
+    private static final ReentrantLock LOCK = new ReentrantLock();
+
     public static final String TOMEE_EJBCONTAINER_HTTP_PORT = "tomee.ejbcontainer.http.port";
     private static final AtomicReference<EmbeddedTomEEContainer> tomEEContainer = new AtomicReference<EmbeddedTomEEContainer>();
     private static final List<String> CONTAINER_NAMES = Arrays.asList(EmbeddedTomEEContainer.class.getName(), "tomee-embedded", "embedded-tomee");
@@ -52,6 +59,7 @@ public final class EmbeddedTomEEContainer extends EJBContainer {
         // no-op
     }
 
+    @SuppressWarnings("unused")
     public Container getDelegate() {
         return container;
     }
@@ -69,30 +77,38 @@ public final class EmbeddedTomEEContainer extends EJBContainer {
 
     @Override
     public void close() {
-        final Collection<Exception> errors = new ArrayList<Exception>();
-        for (final String id : deployedIds) {
-            if (tomEEContainer.get().container.getAppContexts(id) != null) {
-                try {
-                    tomEEContainer.get().container.undeploy(id);
-                } catch (final Exception ex) {
-                    Logger.getInstance(LogCategory.OPENEJB, EmbeddedTomEEContainer.class).error(ex.getMessage(), ex);
-                    errors.add(ex);
+
+        final ReentrantLock lock = LOCK;
+        lock.lock();
+
+        try {
+            final Collection<Exception> errors = new ArrayList<Exception>();
+            for (final String id : deployedIds) {
+                if (tomEEContainer.get().container.getAppContexts(id) != null) {
+                    try {
+                        tomEEContainer.get().container.undeploy(id);
+                    } catch (final Exception ex) {
+                        Logger.getInstance(LogCategory.OPENEJB, EmbeddedTomEEContainer.class).error(ex.getMessage(), ex);
+                        errors.add(ex);
+                    }
                 }
             }
-        }
-        deployedIds.clear();
+            deployedIds.clear();
 
-        try {
-            tomEEContainer.get().container.close();
-        } catch (final Exception ex) {
-            errors.add(ex);
-            Logger.getInstance(LogCategory.OPENEJB, EmbeddedTomEEContainer.class).error(ex.getMessage(), ex);
-        }finally {
-            tomEEContainer.set(null);
-        }
+            try {
+                tomEEContainer.get().container.close();
+            } catch (final Exception ex) {
+                errors.add(ex);
+                Logger.getInstance(LogCategory.OPENEJB, EmbeddedTomEEContainer.class).error(ex.getMessage(), ex);
+            } finally {
+                tomEEContainer.set(null);
+            }
 
-        if (!errors.isEmpty()) {
-            throw Exceptions.newEJBException(new TomEERuntimeException(errors.toString()));
+            if (!errors.isEmpty()) {
+                throw Exceptions.newEJBException(new TomEERuntimeException(errors.toString()));
+            }
+        } finally {
+            lock.unlock();
         }
     }
 
@@ -104,98 +120,106 @@ public final class EmbeddedTomEEContainer extends EJBContainer {
     public static class EmbeddedTomEEContainerProvider implements EJBContainerProvider {
         @Override
         public EJBContainer createEJBContainer(final Map<?, ?> properties) {
-            final Object provider = properties.get(EJBContainer.PROVIDER);
-            int ejbContainerProviders = 1;
-            try {
-                ejbContainerProviders = ProviderLocator.getServices(EJBContainerProvider.class.getName(), EJBContainer.class, Thread.currentThread().getContextClassLoader()).size();
-            } catch (final Exception e) {
-                // no-op
-            }
 
-            if ((provider == null && ejbContainerProviders > 1)
-                    || (!EmbeddedTomEEContainer.class.equals(provider)
-                        && !CONTAINER_NAMES.contains(String.valueOf(provider)))) {
-                return null;
-            }
+            final ReentrantLock lock = LOCK;
+            lock.lock();
 
-            if (tomEEContainer.get() != null) {
-                return tomEEContainer.get();
-            }
+            try {
+                final Object provider = properties.get(EJBContainer.PROVIDER);
+                int ejbContainerProviders = 1;
+                try {
+                    ejbContainerProviders = ProviderLocator.getServices(EJBContainerProvider.class.getName(), EJBContainer.class, Thread.currentThread().getContextClassLoader()).size();
+                } catch (final Exception e) {
+                    // no-op
+                }
 
-            final String appId = (String) properties.get(EJBContainer.APP_NAME);
-            final Object modules = properties.get(EJBContainer.MODULES);
-
-            tomEEContainer.set(new EmbeddedTomEEContainer());
-            final Configuration configuration = new Configuration();
-            if (properties.containsKey(TOMEE_EJBCONTAINER_HTTP_PORT)) {
-                int port;
-                final Object portValue = properties.get(TOMEE_EJBCONTAINER_HTTP_PORT);
-                if (portValue instanceof Integer) {
-                    port = (Integer) portValue;
-                } else if (portValue instanceof String) {
-                    port = Integer.parseInt((String) portValue);
-                } else {
-                    throw new TomEERuntimeException("port value should be an integer or a string");
+                if ((provider == null && ejbContainerProviders > 1)
+                        || (!EmbeddedTomEEContainer.class.equals(provider)
+                        && !CONTAINER_NAMES.contains(String.valueOf(provider)))) {
+                    return null;
                 }
-                if (port <= 0) {
-                    port = NetworkUtil.getNextAvailablePort();
+
+                if (tomEEContainer.get() != null) {
+                    return tomEEContainer.get();
                 }
-                configuration.setHttpPort(port);
-            }
-            System.setProperty(TOMEE_EJBCONTAINER_HTTP_PORT, Integer.toString(configuration.getHttpPort()));
-            tomEEContainer.get().container.setup(configuration);
-            try {
-                tomEEContainer.get().container.start();
-
-                if (modules instanceof File) {
-                    tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, ((File) modules), appId != null).getId());
-                } else if (modules instanceof String) {
-                    tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, new File((String) modules), appId != null).getId());
-                } else if (modules instanceof String[]) {
-                    for (final String path : (String[]) modules) {
-                        tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, new File(path), appId != null).getId());
+
+                final String appId = (String) properties.get(EJBContainer.APP_NAME);
+                final Object modules = properties.get(EJBContainer.MODULES);
+
+                tomEEContainer.set(new EmbeddedTomEEContainer());
+                final Configuration configuration = new Configuration();
+                if (properties.containsKey(TOMEE_EJBCONTAINER_HTTP_PORT)) {
+                    int port;
+                    final Object portValue = properties.get(TOMEE_EJBCONTAINER_HTTP_PORT);
+                    if (portValue instanceof Integer) {
+                        port = (Integer) portValue;
+                    } else if (portValue instanceof String) {
+                        port = Integer.parseInt((String) portValue);
+                    } else {
+                        throw new TomEERuntimeException("port value should be an integer or a string");
                     }
-                } else if (modules instanceof File[]) {
-                    for (final File file : (File[]) modules) {
-                        tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, file, appId != null).getId());
+                    if (port <= 0) {
+                        port = NetworkUtil.getNextAvailablePort();
                     }
-                } else {
-                    SystemInstance.get().getProperties().putAll(properties);
-                    final Collection<File> files = tomEEContainer.get().container.getConfigurationFactory().getModulesFromClassPath(null, Thread.currentThread().getContextClassLoader());
-                    if (files.size() == 0) {
-                        try {
-                            tomEEContainer.get().close();
-                        } catch (final Exception e) {
-                            // no-op
+                    configuration.setHttpPort(port);
+                }
+                System.setProperty(TOMEE_EJBCONTAINER_HTTP_PORT, Integer.toString(configuration.getHttpPort()));
+                tomEEContainer.get().container.setup(configuration);
+                try {
+                    tomEEContainer.get().container.start();
+
+                    if (modules instanceof File) {
+                        tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, ((File) modules), appId != null).getId());
+                    } else if (modules instanceof String) {
+                        tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, new File((String) modules), appId != null).getId());
+                    } else if (modules instanceof String[]) {
+                        for (final String path : (String[]) modules) {
+                            tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, new File(path), appId != null).getId());
+                        }
+                    } else if (modules instanceof File[]) {
+                        for (final File file : (File[]) modules) {
+                            tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, file, appId != null).getId());
+                        }
+                    } else {
+                        SystemInstance.get().getProperties().putAll(properties);
+                        final Collection<File> files = tomEEContainer.get().container.getConfigurationFactory().getModulesFromClassPath(null, Thread.currentThread().getContextClassLoader());
+                        if (files.size() == 0) {
+                            try {
+                                tomEEContainer.get().close();
+                            } catch (final Exception e) {
+                                // no-op
+                            }
+                            tomEEContainer.set(null);
+                            throw Exceptions.newNoModulesFoundException();
+                        }
+                        for (final File file : files) {
+                            tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, file, appId != null).getId());
                         }
-                        tomEEContainer.set(null);
-                        throw Exceptions.newNoModulesFoundException();
-                    }
-                    for (final File file : files) {
-                        tomEEContainer.get().deployedIds.add(tomEEContainer.get().container.deploy(appId, file, appId != null).getId());
                     }
-                }
 
-                return tomEEContainer.get();
-            } catch (final OpenEJBException e) {
-                tomEEContainer.get().close();
-                throw new EJBException(e);
-            } catch (final MalformedURLException e) {
-                tomEEContainer.get().close();
-                throw new EJBException(e);
-            } catch (final ValidationException ve) {
-                if (tomEEContainer.get() != null) {
+                    return tomEEContainer.get();
+                } catch (final OpenEJBException e) {
                     tomEEContainer.get().close();
-                }
-                throw ve;
-            } catch (final Exception e) {
-                if (tomEEContainer.get() != null) {
+                    throw new EJBException(e);
+                } catch (final MalformedURLException e) {
                     tomEEContainer.get().close();
+                    throw new EJBException(e);
+                } catch (final ValidationException ve) {
+                    if (tomEEContainer.get() != null) {
+                        tomEEContainer.get().close();
+                    }
+                    throw ve;
+                } catch (final Exception e) {
+                    if (tomEEContainer.get() != null) {
+                        tomEEContainer.get().close();
+                    }
+                    if (e instanceof EJBException) {
+                        throw (EJBException) e;
+                    }
+                    throw new TomEERuntimeException("initialization exception", e);
                 }
-                if (e instanceof EJBException) {
-                    throw (EJBException) e;
-                }
-                throw new TomEERuntimeException("initialization exception", e);
+            } finally {
+                lock.unlock();
             }
         }
     }