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

[1/2] tomee git commit: TOMEE-1702 dont store cmp reference globally

Repository: tomee
Updated Branches:
  refs/heads/master eb0c2da70 -> 1a3f66df2


TOMEE-1702 dont store cmp reference globally


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

Branch: refs/heads/master
Commit: dac782064fa1b356686a845f385eca1c2a5534fa
Parents: eb0c2da
Author: Romain manni-Bucau <rm...@gmail.com>
Authored: Tue Feb 2 12:25:55 2016 +0100
Committer: Romain manni-Bucau <rm...@gmail.com>
Committed: Tue Feb 2 12:25:55 2016 +0100

----------------------------------------------------------------------
 .../openejb/core/ivm/BaseEjbProxyHandler.java   | 104 ++++++--
 .../openejb/core/cmp/jpa/SimpleCmpTest.java     | 244 +++++++++++++++++++
 2 files changed, 333 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/dac78206/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java b/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
index ac0e1dd..309b359 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/BaseEjbProxyHandler.java
@@ -23,12 +23,31 @@ import org.apache.openejb.InterfaceType;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.ProxyInfo;
 import org.apache.openejb.RpcContainer;
+import org.apache.openejb.core.Operation;
 import org.apache.openejb.core.ThreadContext;
+import org.apache.openejb.core.ThreadContextListener;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.proxy.LocalBeanProxyFactory;
 
+import javax.ejb.AccessLocalException;
+import javax.ejb.EJBException;
+import javax.ejb.EJBTransactionRequiredException;
+import javax.ejb.EJBTransactionRolledbackException;
+import javax.ejb.NoSuchEJBException;
+import javax.ejb.NoSuchObjectLocalException;
+import javax.ejb.TransactionRequiredLocalException;
+import javax.ejb.TransactionRolledbackLocalException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionRequiredException;
+import javax.transaction.TransactionRolledbackException;
+import javax.transaction.TransactionSynchronizationRegistry;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -54,16 +73,6 @@ import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.ReentrantLock;
-import javax.ejb.AccessLocalException;
-import javax.ejb.EJBException;
-import javax.ejb.EJBTransactionRequiredException;
-import javax.ejb.EJBTransactionRolledbackException;
-import javax.ejb.NoSuchEJBException;
-import javax.ejb.NoSuchObjectLocalException;
-import javax.ejb.TransactionRequiredLocalException;
-import javax.ejb.TransactionRolledbackLocalException;
-import javax.transaction.TransactionRequiredException;
-import javax.transaction.TransactionRolledbackException;
 
 import static org.apache.openejb.core.ivm.IntraVmCopyMonitor.State.CLASSLOADER_COPY;
 import static org.apache.openejb.core.ivm.IntraVmCopyMonitor.State.COPY;
@@ -74,6 +83,25 @@ public abstract class BaseEjbProxyHandler implements InvocationHandler, Serializ
 
     private static final String OPENEJB_LOCALCOPY = "openejb.localcopy";
     private static final boolean REMOTE_COPY_ENABLED = parseRemoteCopySetting();
+    static {
+        ThreadContext.addThreadContextListener(new ThreadContextListener() {
+            @Override
+            public void contextEntered(final ThreadContext oldContext, final ThreadContext newContext) {
+                // no-op
+            }
+
+            @Override
+            public void contextExited(final ThreadContext exitedContext, final ThreadContext reenteredContext) {
+                if (exitedContext != null) {
+                    final ProxyRegistry proxyRegistry = exitedContext.get(ProxyRegistry.class);
+                    if (proxyRegistry != null) {
+                        proxyRegistry.liveHandleRegistry.clear();
+                    }
+                }
+            }
+        });
+    }
+
     public final Object deploymentID;
     public final Object primaryKey;
     protected final InterfaceType interfaceType;
@@ -640,12 +668,58 @@ public abstract class BaseEjbProxyHandler implements InvocationHandler, Serializ
 
     public ConcurrentMap getLiveHandleRegistry() {
         final BeanContext beanContext = getBeanContext();
-        ProxyRegistry proxyRegistry = beanContext.get(ProxyRegistry.class);
-        if (proxyRegistry == null) {
-            proxyRegistry = new ProxyRegistry();
-            beanContext.set(ProxyRegistry.class, proxyRegistry);
+
+        final ThreadContext tc = ThreadContext.getThreadContext();
+        if (tc != null && tc.getBeanContext() != beanContext /* parent bean */ && tc.getCurrentOperation() == Operation.BUSINESS) {
+            ProxyRegistry registry = tc.get(ProxyRegistry.class);
+            if (registry == null) {
+                registry = new ProxyRegistry();
+                tc.set(ProxyRegistry.class, registry);
+            }
+            return registry.liveHandleRegistry;
+        } else { // use the tx if there
+            final SystemInstance systemInstance = SystemInstance.get();
+            final TransactionManager txMgr = systemInstance.getComponent(TransactionManager.class);
+            try {
+                final Transaction tx = txMgr.getTransaction();
+                if (tx != null && tx.getStatus() == Status.STATUS_ACTIVE) {
+                    final TransactionSynchronizationRegistry registry = systemInstance.getComponent(TransactionSynchronizationRegistry.class);
+                    final String resourceKey = ProxyRegistry.class.getName();
+                    ConcurrentMap map = ConcurrentMap.class.cast(registry.getResource(resourceKey));
+                    if (map == null) {
+                        map = new ConcurrentHashMap();
+                        registry.putResource(resourceKey, map);
+                        try {
+                            final ConcurrentMap tmp = map;
+                            tx.registerSynchronization(new Synchronization() {
+                                @Override
+                                public void beforeCompletion() {
+                                    // no-op
+                                }
+
+                                @Override
+                                public void afterCompletion(final int status) {
+                                    tmp.clear();
+                                }
+                            });
+                        } catch (final RollbackException e) { // not really possible since we check the status
+                            // let it go to default
+                        }
+                    }
+                    return map;
+                }
+            } catch (final SystemException e) {
+                // let it go to default
+            }
+
+            // back to default but it doesnt release the memory
+            ProxyRegistry proxyRegistry = beanContext.get(ProxyRegistry.class);
+            if (proxyRegistry == null) {
+                proxyRegistry = new ProxyRegistry();
+                beanContext.set(ProxyRegistry.class, proxyRegistry);
+            }
+            return proxyRegistry.liveHandleRegistry;
         }
-        return proxyRegistry.liveHandleRegistry;
     }
 
     private void writeObject(final ObjectOutputStream out) throws IOException {

http://git-wip-us.apache.org/repos/asf/tomee/blob/dac78206/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SimpleCmpTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SimpleCmpTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SimpleCmpTest.java
new file mode 100644
index 0000000..9ff4557
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/SimpleCmpTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.cmp.jpa;
+
+import org.apache.activemq.util.ByteArrayInputStream;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.config.ReadDescriptors;
+import org.apache.openejb.core.entity.EntityContext;
+import org.apache.openejb.core.entity.EntityEjbHomeHandler;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.AppResource;
+import org.apache.openejb.testing.Module;
+import org.apache.openejb.testing.SimpleLog;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.CreateException;
+import javax.ejb.EJBException;
+import javax.ejb.EJBLocalObject;
+import javax.ejb.EntityBean;
+import javax.ejb.RemoveException;
+import javax.ejb.SessionBean;
+import javax.ejb.SessionContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.lang.reflect.Proxy;
+import java.rmi.RemoteException;
+
+import static org.junit.Assert.assertNotNull;
+
+@SimpleLog
+@RunWith(ApplicationComposer.class)
+public class SimpleCmpTest {
+    @AppResource
+    private Context ctx;
+
+    @Test
+    public void checkNoLeak() throws NamingException, RemoteException {
+        TestBeanEJBHome home = (TestBeanEJBHome) ctx.lookup("TestBeanRemoteHome");
+        TestBeanEJBObject bean = home.create();
+
+        bean.check(bean.createHotelBean(0)); // the bean has the asserts
+    }
+
+    @Module
+    public EjbJar jar() throws OpenEJBException {
+        return ReadDescriptors.readEjbJar(new ByteArrayInputStream(
+                ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+                        "<ejb-jar xsi:schemaLocation=\"" +
+                        "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd\" " +
+                        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
+                        "xmlns=\"http://java.sun.com/xml/ns/j2ee\" version=\"2.1\" id=\"ejb-jar_ID\">\n" +
+                        "<display-name>OMEApp</display-name>\n" +
+                        "<enterprise-beans>\n" +
+                        "<entity id=\"ContainerManagedEntity_1\">\n" +
+                        "<ejb-name>HotelBean</ejb-name>\n" +
+                        "<local-home>" + HotelEJBLocalHome.class.getName() + "</local-home>\n" +
+                        "<local>" + HotelEJBLocalObject.class.getName() + "</local>\n" +
+                        "<ejb-class>" + HotelBean.class.getName() + "</ejb-class>\n" +
+                        "<persistence-type>Container</persistence-type>\n" +
+                        "<prim-key-class>java.lang.String</prim-key-class>\n" +
+                        "<reentrant>false</reentrant>\n" +
+                        "<cmp-version>2.x</cmp-version>\n" +
+                        "<abstract-schema-name>HotelBean</abstract-schema-name>\n" +
+                        "<cmp-field id=\"HotelBean_primKey\">\n" +
+                        "<field-name>hotelId</field-name>\n" +
+                        "</cmp-field>\n" +
+                        "<cmp-field id=\"HotelBean_name\">\n" +
+                        "<field-name>hotelname</field-name>\n" +
+                        "</cmp-field>\n" +
+                        "<primkey-field>hotelId</primkey-field>\n" +
+                        "</entity>\n" +
+                        "<session>\n" +
+                        "<ejb-name>TestBean</ejb-name>\n" +
+                        "<home>" + TestBeanEJBHome.class.getName() + "</home>\n" +
+                        "<remote>" + TestBeanEJBObject.class.getName() + "</remote>\n" +
+                        "<local-home>" + TestBeanEJBLocalHome.class.getName() + "</local-home>\n" +
+                        "<local>" + TestBeanEJBLocalObject.class.getName() + "</local>\n" +
+                        "<ejb-class>" + TestBean.class.getName() + "</ejb-class>\n" +
+                        "<session-type>Stateless</session-type>\n" +
+                        "<transaction-type>Container</transaction-type>\n" +
+                        "<ejb-local-ref>\n" +
+                        "<ejb-ref-name>ejb/HotelEJBLocalHome</ejb-ref-name>\n" +
+                        "<ejb-ref-type>Entity</ejb-ref-type>\n" +
+                        "<local-home>" + HotelEJBLocalHome.class.getName() + "</local-home>\n" +
+                        "<local>" + HotelEJBLocalObject.class.getName() + "</local>\n" +
+                        "</ejb-local-ref>\n" +
+                        "</session>\n" +
+                        "</enterprise-beans>\n" +
+                        "</ejb-jar>").getBytes()));
+    }
+
+    public interface HotelEJBLocalHome extends javax.ejb.EJBLocalHome {
+        HotelEJBLocalObject create(String id, String name) throws CreateException;
+        HotelEJBLocalObject findByPrimaryKey(String id);
+    }
+
+    public interface TestBeanEJBHome extends javax.ejb.EJBHome {
+        TestBeanEJBObject create() throws RemoteException;
+    }
+
+    public interface TestBeanEJBLocalHome extends javax.ejb.EJBLocalHome {
+
+        TestBeanEJBLocalObject create();
+    }
+
+    public interface TestBeanEJBLocalObject extends javax.ejb.EJBLocalObject {
+        void createHotelBean(int num) throws CreateException;
+    }
+
+    public static class TestBean implements SessionBean {
+
+        private static final long serialVersionUID = 1L;
+        protected SessionContext sessionContext;
+        private HotelEJBLocalHome hotel;
+
+        public void ejbCreate() {
+        }
+
+        public void ejbPassivate() throws EJBException, RemoteException {
+        }
+
+        public void ejbRemove() throws EJBException, RemoteException {
+        }
+
+        public void setSessionContext(SessionContext arg0) throws EJBException,
+                RemoteException {
+            this.sessionContext = arg0;
+        }
+
+        public void ejbActivate() throws EJBException, RemoteException {
+        }
+
+        public Object createHotelBean(int num) throws CreateException {
+            hotel = (HotelEJBLocalHome) this.sessionContext.lookup("ejb/HotelEJBLocalHome");
+            final String pk = hotel.create(String.valueOf(num), "Some Hotel").getPrimaryKey().toString();
+            assertNotNull(hotel.findByPrimaryKey(pk));
+            return pk;
+        }
+
+        public void check(final String pk) {
+            hotel = (HotelEJBLocalHome) this.sessionContext.lookup("ejb/HotelEJBLocalHome");
+
+            // main part of the test is there
+            final EntityEjbHomeHandler handler = EntityEjbHomeHandler.class.cast(Proxy.getInvocationHandler(hotel));
+            try {
+                final Object registry = handler.getBeanContext().get(
+                        Thread.currentThread().getContextClassLoader() // private so use reflection
+                                .loadClass("org.apache.openejb.core.ivm.BaseEjbProxyHandler$ProxyRegistry"));
+                assertNotNull(registry); // not even instantiated since we have a wrapper (stateless)
+            } catch (final ClassNotFoundException e) {
+                throw new IllegalStateException(e);
+            }
+
+            // ensure we didn't deleted the entry
+            assertNotNull(hotel.findByPrimaryKey(pk));
+        }
+    }
+
+    public interface HotelEJBLocalObject extends EJBLocalObject {
+
+        java.lang.String getHotelId();
+
+        void setHotelId(java.lang.String hotelId);
+
+        String getHotelname();
+
+        void setHotelname(String hotelname);
+    }
+
+    public interface TestBeanEJBObject extends javax.ejb.EJBObject {
+        String createHotelBean(int num) throws RemoteException;
+        void check(String pk) throws RemoteException;
+    }
+
+    public static abstract class HotelBean implements EntityBean {
+        private static final long serialVersionUID = -1740314851444302078L;
+
+
+        public String ejbCreate(String id, String name) throws CreateException {
+            this.setHotelId(id);
+            this.setHotelname(name);
+            return null;
+        }
+
+        public abstract java.lang.String getHotelId();
+
+        public abstract void setHotelId(java.lang.String hotelId);
+
+        public abstract String getHotelname();
+
+        public abstract void setHotelname(String hotelname);
+
+        public void ejbPostCreate(String str1, String str2)
+                throws CreateException {
+        }
+
+
+        public void ejbRemove() throws RemoveException, EJBException,
+                RemoteException {
+            // no-op
+        }
+
+        public void ejbActivate() throws EJBException, RemoteException {
+            // no-op
+        }
+
+        public void ejbLoad() throws EJBException, RemoteException {
+            // no-op
+        }
+
+        public void ejbPassivate() throws EJBException, RemoteException {
+            // no-op
+        }
+
+        public void ejbStore() throws EJBException, RemoteException {
+            // no-op
+        }
+
+        public void setEntityContext(EntityContext arg0) throws EJBException,
+                RemoteException {
+            // no-op
+        }
+
+        public void unsetEntityContext() throws EJBException, RemoteException {
+            // no-op
+        }
+    }
+}


[2/2] tomee git commit: TOMEE-1703 pushing the finder to webapp deployment to be able to scan even in ear deployment lifecycle - this can need a small rework of the deployment to make module tree available in webapp builder somehow in a clear way

Posted by rm...@apache.org.
TOMEE-1703 pushing the finder to webapp deployment to be able to scan even in ear deployment lifecycle - this can need a small rework of the deployment to make module tree available in webapp builder somehow in a clear way


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

Branch: refs/heads/master
Commit: 1a3f66df292fb23d095fbab4704d2fa40a935c24
Parents: dac7820
Author: Romain manni-Bucau <rm...@gmail.com>
Authored: Tue Feb 2 12:26:54 2016 +0100
Committer: Romain manni-Bucau <rm...@gmail.com>
Committed: Tue Feb 2 12:26:54 2016 +0100

----------------------------------------------------------------------
 .../openejb/assembler/classic/Assembler.java    | 537 ++++++++++---------
 .../openejb/config/ConfigurationFactory.java    |  12 +
 .../tomee/catalina/TomcatWebAppBuilder.java     | 274 +++++-----
 3 files changed, 437 insertions(+), 386 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/1a3f66df/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
index ef6544b..7546a33 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
@@ -696,330 +696,337 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
 
     private AppContext createApplication(final AppInfo appInfo, ClassLoader classLoader, final boolean start) throws OpenEJBException, IOException, NamingException {
         try {
-            mergeServices(appInfo);
-        } catch (final URISyntaxException e) {
-            logger.info("Can't merge resources.xml services and appInfo.properties");
-        }
+            try {
+                mergeServices(appInfo);
+            } catch (final URISyntaxException e) {
+                logger.info("Can't merge resources.xml services and appInfo.properties");
+            }
 
-        // The path is used in the UrlCache, command line deployer, JNDI name templates, tomcat integration and a few other places
-        if (appInfo.appId == null) {
-            throw new IllegalArgumentException("AppInfo.appId cannot be null");
-        }
-        if (appInfo.path == null) {
-            appInfo.path = appInfo.appId;
-        }
+            // The path is used in the UrlCache, command line deployer, JNDI name templates, tomcat integration and a few other places
+            if (appInfo.appId == null) {
+                throw new IllegalArgumentException("AppInfo.appId cannot be null");
+            }
+            if (appInfo.path == null) {
+                appInfo.path = appInfo.appId;
+            }
 
-        Extensions.addExtensions(classLoader, appInfo.eventClassesNeedingAppClassloader);
-        logger.info("createApplication.start", appInfo.path);
-        final Context containerSystemContext = containerSystem.getJNDIContext();
-        
-        // To start out, ensure we don't already have any beans deployed with duplicate IDs.  This
-        // is a conflict we can't handle.
-        final List<String> used = new ArrayList<String>();
-        for (final EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
-            for (final EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) {
-                if (containerSystem.getBeanContext(beanInfo.ejbDeploymentId) != null) {
-                    used.add(beanInfo.ejbDeploymentId);
+            Extensions.addExtensions(classLoader, appInfo.eventClassesNeedingAppClassloader);
+            logger.info("createApplication.start", appInfo.path);
+            final Context containerSystemContext = containerSystem.getJNDIContext();
+
+            // To start out, ensure we don't already have any beans deployed with duplicate IDs.  This
+            // is a conflict we can't handle.
+            final List<String> used = new ArrayList<String>();
+            for (final EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
+                for (final EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) {
+                    if (containerSystem.getBeanContext(beanInfo.ejbDeploymentId) != null) {
+                        used.add(beanInfo.ejbDeploymentId);
+                    }
                 }
             }
-        }
 
-        if (used.size() > 0) {
-            String message = logger.error("createApplication.appFailedDuplicateIds", appInfo.path);
-            for (final String id : used) {
-                logger.error("createApplication.deploymentIdInUse", id);
-                message += "\n    " + id;
+            if (used.size() > 0) {
+                String message = logger.error("createApplication.appFailedDuplicateIds", appInfo.path);
+                for (final String id : used) {
+                    logger.error("createApplication.deploymentIdInUse", id);
+                    message += "\n    " + id;
+                }
+                throw new DuplicateDeploymentIdException(message);
             }
-            throw new DuplicateDeploymentIdException(message);
-        }
 
-        //Construct the global and app jndi contexts for this app
-        final InjectionBuilder injectionBuilder = new InjectionBuilder(classLoader);
+            //Construct the global and app jndi contexts for this app
+            final InjectionBuilder injectionBuilder = new InjectionBuilder(classLoader);
 
-        final Set<Injection> injections = new HashSet<Injection>();
-        injections.addAll(injectionBuilder.buildInjections(appInfo.globalJndiEnc));
-        injections.addAll(injectionBuilder.buildInjections(appInfo.appJndiEnc));
+            final Set<Injection> injections = new HashSet<Injection>();
+            injections.addAll(injectionBuilder.buildInjections(appInfo.globalJndiEnc));
+            injections.addAll(injectionBuilder.buildInjections(appInfo.appJndiEnc));
 
-        final JndiEncBuilder globalBuilder = new JndiEncBuilder(appInfo.globalJndiEnc, injections, appInfo.appId, null, GLOBAL_UNIQUE_ID, classLoader, appInfo.properties);
-        final Map<String, Object> globalBindings = globalBuilder.buildBindings(JndiEncBuilder.JndiScope.global);
-        final Context globalJndiContext = globalBuilder.build(globalBindings);
+            final JndiEncBuilder globalBuilder = new JndiEncBuilder(appInfo.globalJndiEnc, injections, appInfo.appId, null, GLOBAL_UNIQUE_ID, classLoader, appInfo.properties);
+            final Map<String, Object> globalBindings = globalBuilder.buildBindings(JndiEncBuilder.JndiScope.global);
+            final Context globalJndiContext = globalBuilder.build(globalBindings);
 
-        final JndiEncBuilder appBuilder = new JndiEncBuilder(appInfo.appJndiEnc, injections, appInfo.appId, null, appInfo.appId, classLoader, appInfo.properties);
-        final Map<String, Object> appBindings = appBuilder.buildBindings(JndiEncBuilder.JndiScope.app);
-        final Context appJndiContext = appBuilder.build(appBindings);
+            final JndiEncBuilder appBuilder = new JndiEncBuilder(appInfo.appJndiEnc, injections, appInfo.appId, null, appInfo.appId, classLoader, appInfo.properties);
+            final Map<String, Object> appBindings = appBuilder.buildBindings(JndiEncBuilder.JndiScope.app);
+            final Context appJndiContext = appBuilder.build(appBindings);
 
-        try {
-            // Generate the cmp2/cmp1 concrete subclasses
-            final CmpJarBuilder cmpJarBuilder = new CmpJarBuilder(appInfo, classLoader);
-            final File generatedJar = cmpJarBuilder.getJarFile();
-            if (generatedJar != null) {
-                classLoader = ClassLoaderUtil.createClassLoader(appInfo.path, new URL[]{generatedJar.toURI().toURL()}, classLoader);
-            }
-
-            final AppContext appContext = new AppContext(appInfo.appId, SystemInstance.get(), classLoader, globalJndiContext, appJndiContext, appInfo.standaloneModule);
-            appContext.getProperties().putAll(appInfo.properties);
-            appContext.getInjections().addAll(injections);
-            appContext.getBindings().putAll(globalBindings);
-            appContext.getBindings().putAll(appBindings);
-
-            containerSystem.addAppContext(appContext);
-
-            appContext.set(AsynchronousPool.class, AsynchronousPool.create(appContext));
-
-            final Map<String, LazyValidatorFactory> lazyValidatorFactories = new HashMap<String, LazyValidatorFactory>();
-            final Map<String, LazyValidator> lazyValidators = new HashMap<String, LazyValidator>();
-            final boolean isGeronimo = SystemInstance.get().hasProperty("openejb.geronimo");
-
-            // try to not create N times the same validator for a single app
-            final Map<ComparableValidationConfig, ValidatorFactory> validatorFactoriesByConfig = new HashMap<ComparableValidationConfig, ValidatorFactory>();
-            if (!isGeronimo) {
-                // Bean Validation
-                // ValidatorFactory needs to be put in the map sent to the entity manager factory
-                // so it has to be constructed before
-                final List<CommonInfoObject> vfs = listCommonInfoObjectsForAppInfo(appInfo);
-                final Map<String, ValidatorFactory> validatorFactories = new HashMap<String, ValidatorFactory>();
-
-                for (final CommonInfoObject info : vfs) {
-                    if (info.validationInfo == null) {
-                        continue;
-                    }
-
-                    final ComparableValidationConfig conf = new ComparableValidationConfig(
-                            info.validationInfo.providerClassName, info.validationInfo.messageInterpolatorClass,
-                            info.validationInfo.traversableResolverClass, info.validationInfo.constraintFactoryClass,
-                            info.validationInfo.parameterNameProviderClass, info.validationInfo.version,
-                            info.validationInfo.propertyTypes, info.validationInfo.constraintMappings,
-                            info.validationInfo.executableValidationEnabled, info.validationInfo.validatedTypes
-                    );
-                    ValidatorFactory factory = validatorFactoriesByConfig.get(conf);
-                    if (factory == null) {
-                        try { // lazy cause of CDI :(
-                            final LazyValidatorFactory handler = new LazyValidatorFactory(classLoader, info.validationInfo);
-                            factory = (ValidatorFactory) Proxy.newProxyInstance(
-                                    appContext.getClassLoader(), VALIDATOR_FACTORY_INTERFACES, handler);
-                            lazyValidatorFactories.put(info.uniqueId, handler);
-                        } catch (final ValidationException ve) {
-                            logger.warning("can't build the validation factory for module " + info.uniqueId, ve);
+            try {
+                // Generate the cmp2/cmp1 concrete subclasses
+                final CmpJarBuilder cmpJarBuilder = new CmpJarBuilder(appInfo, classLoader);
+                final File generatedJar = cmpJarBuilder.getJarFile();
+                if (generatedJar != null) {
+                    classLoader = ClassLoaderUtil.createClassLoader(appInfo.path, new URL[]{generatedJar.toURI().toURL()}, classLoader);
+                }
+
+                final AppContext appContext = new AppContext(appInfo.appId, SystemInstance.get(), classLoader, globalJndiContext, appJndiContext, appInfo.standaloneModule);
+                appContext.getProperties().putAll(appInfo.properties);
+                appContext.getInjections().addAll(injections);
+                appContext.getBindings().putAll(globalBindings);
+                appContext.getBindings().putAll(appBindings);
+
+                containerSystem.addAppContext(appContext);
+
+                appContext.set(AsynchronousPool.class, AsynchronousPool.create(appContext));
+
+                final Map<String, LazyValidatorFactory> lazyValidatorFactories = new HashMap<String, LazyValidatorFactory>();
+                final Map<String, LazyValidator> lazyValidators = new HashMap<String, LazyValidator>();
+                final boolean isGeronimo = SystemInstance.get().hasProperty("openejb.geronimo");
+
+                // try to not create N times the same validator for a single app
+                final Map<ComparableValidationConfig, ValidatorFactory> validatorFactoriesByConfig = new HashMap<ComparableValidationConfig, ValidatorFactory>();
+                if (!isGeronimo) {
+                    // Bean Validation
+                    // ValidatorFactory needs to be put in the map sent to the entity manager factory
+                    // so it has to be constructed before
+                    final List<CommonInfoObject> vfs = listCommonInfoObjectsForAppInfo(appInfo);
+                    final Map<String, ValidatorFactory> validatorFactories = new HashMap<String, ValidatorFactory>();
+
+                    for (final CommonInfoObject info : vfs) {
+                        if (info.validationInfo == null) {
                             continue;
                         }
-                        validatorFactoriesByConfig.put(conf, factory);
-                    } else {
-                        lazyValidatorFactories.put(info.uniqueId, LazyValidatorFactory.class.cast(Proxy.getInvocationHandler(factory)));
-                    }
-                    validatorFactories.put(info.uniqueId, factory);
-                }
 
-                // validators bindings
-                for (final Entry<String, ValidatorFactory> validatorFactory : validatorFactories.entrySet()) {
-                    final String id = validatorFactory.getKey();
-                    final ValidatorFactory factory = validatorFactory.getValue();
-                    try {
-                        containerSystemContext.bind(VALIDATOR_FACTORY_NAMING_CONTEXT + id, factory);
+                        final ComparableValidationConfig conf = new ComparableValidationConfig(
+                                info.validationInfo.providerClassName, info.validationInfo.messageInterpolatorClass,
+                                info.validationInfo.traversableResolverClass, info.validationInfo.constraintFactoryClass,
+                                info.validationInfo.parameterNameProviderClass, info.validationInfo.version,
+                                info.validationInfo.propertyTypes, info.validationInfo.constraintMappings,
+                                info.validationInfo.executableValidationEnabled, info.validationInfo.validatedTypes
+                        );
+                        ValidatorFactory factory = validatorFactoriesByConfig.get(conf);
+                        if (factory == null) {
+                            try { // lazy cause of CDI :(
+                                final LazyValidatorFactory handler = new LazyValidatorFactory(classLoader, info.validationInfo);
+                                factory = (ValidatorFactory) Proxy.newProxyInstance(
+                                        appContext.getClassLoader(), VALIDATOR_FACTORY_INTERFACES, handler);
+                                lazyValidatorFactories.put(info.uniqueId, handler);
+                            } catch (final ValidationException ve) {
+                                logger.warning("can't build the validation factory for module " + info.uniqueId, ve);
+                                continue;
+                            }
+                            validatorFactoriesByConfig.put(conf, factory);
+                        } else {
+                            lazyValidatorFactories.put(info.uniqueId, LazyValidatorFactory.class.cast(Proxy.getInvocationHandler(factory)));
+                        }
+                        validatorFactories.put(info.uniqueId, factory);
+                    }
 
-                        Validator validator;
+                    // validators bindings
+                    for (final Entry<String, ValidatorFactory> validatorFactory : validatorFactories.entrySet()) {
+                        final String id = validatorFactory.getKey();
+                        final ValidatorFactory factory = validatorFactory.getValue();
                         try {
-                            final LazyValidator lazyValidator = new LazyValidator(factory);
-                            validator = (Validator) Proxy.newProxyInstance(appContext.getClassLoader(), VALIDATOR_INTERFACES, lazyValidator);
-                            lazyValidators.put(id, lazyValidator);
+                            containerSystemContext.bind(VALIDATOR_FACTORY_NAMING_CONTEXT + id, factory);
+
+                            Validator validator;
+                            try {
+                                final LazyValidator lazyValidator = new LazyValidator(factory);
+                                validator = (Validator) Proxy.newProxyInstance(appContext.getClassLoader(), VALIDATOR_INTERFACES, lazyValidator);
+                                lazyValidators.put(id, lazyValidator);
+                            } catch (final Exception e) {
+                                logger.error(e.getMessage(), e);
+                                continue;
+                            }
+
+                            containerSystemContext.bind(VALIDATOR_NAMING_CONTEXT + id, validator);
+                        } catch (final NameAlreadyBoundException e) {
+                            throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
                         } catch (final Exception e) {
-                            logger.error(e.getMessage(), e);
-                            continue;
+                            throw new OpenEJBException(e);
                         }
+                    }
 
-                        containerSystemContext.bind(VALIDATOR_NAMING_CONTEXT + id, validator);
+                    validatorFactories.clear();
+                }
+
+                // JPA - Persistence Units MUST be processed first since they will add ClassFileTransformers
+                // to the class loader which must be added before any classes are loaded
+                final Map<String, String> units = new HashMap<String, String>();
+                final PersistenceBuilder persistenceBuilder = new PersistenceBuilder(persistenceClassLoaderHandler);
+                for (final PersistenceUnitInfo info : appInfo.persistenceUnits) {
+                    final ReloadableEntityManagerFactory factory;
+                    try {
+                        factory = persistenceBuilder.createEntityManagerFactory(info, classLoader, validatorFactoriesByConfig);
+                        containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT + info.id, factory);
+                        units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT + info.id);
                     } catch (final NameAlreadyBoundException e) {
-                        throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
+                        throw new OpenEJBException("PersistenceUnit already deployed: " + info.persistenceUnitRootUrl);
                     } catch (final Exception e) {
                         throw new OpenEJBException(e);
                     }
-                }
-
-                validatorFactories.clear();
-            }
 
-            // JPA - Persistence Units MUST be processed first since they will add ClassFileTransformers
-            // to the class loader which must be added before any classes are loaded
-            final Map<String, String> units = new HashMap<String, String>();
-            final PersistenceBuilder persistenceBuilder = new PersistenceBuilder(persistenceClassLoaderHandler);
-            for (final PersistenceUnitInfo info : appInfo.persistenceUnits) {
-                final ReloadableEntityManagerFactory factory;
-                try {
-                    factory = persistenceBuilder.createEntityManagerFactory(info, classLoader, validatorFactoriesByConfig);
-                    containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT + info.id, factory);
-                    units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT + info.id);
-                } catch (final NameAlreadyBoundException e) {
-                    throw new OpenEJBException("PersistenceUnit already deployed: " + info.persistenceUnitRootUrl);
-                } catch (final Exception e) {
-                    throw new OpenEJBException(e);
+                    factory.register();
                 }
 
-                factory.register();
-            }
+                logger.debug("Loaded peristence units: " + units);
 
-            logger.debug("Loaded peristence units: " + units);
-
-            // Connectors
-            for (final ConnectorInfo connector : appInfo.connectors) {
-                final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
-                Thread.currentThread().setContextClassLoader(classLoader);
-                try {
-                    // todo add undeployment code for these
-                    if (connector.resourceAdapter != null) {
-                        createResource(connector.resourceAdapter);
-                    }
-                    for (final ResourceInfo outbound : connector.outbound) {
-                        createResource(outbound);
-                        outbound.properties.setProperty("openejb.connector", "true"); // set it after as a marker but not as an attribute (no getOpenejb().setConnector(...))
-                    }
-                    for (final MdbContainerInfo inbound : connector.inbound) {
-                        createContainer(inbound);
-                    }
-                    for (final ResourceInfo adminObject : connector.adminObject) {
-                        createResource(adminObject);
+                // Connectors
+                for (final ConnectorInfo connector : appInfo.connectors) {
+                    final ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+                    Thread.currentThread().setContextClassLoader(classLoader);
+                    try {
+                        // todo add undeployment code for these
+                        if (connector.resourceAdapter != null) {
+                            createResource(connector.resourceAdapter);
+                        }
+                        for (final ResourceInfo outbound : connector.outbound) {
+                            createResource(outbound);
+                            outbound.properties.setProperty("openejb.connector", "true"); // set it after as a marker but not as an attribute (no getOpenejb().setConnector(...))
+                        }
+                        for (final MdbContainerInfo inbound : connector.inbound) {
+                            createContainer(inbound);
+                        }
+                        for (final ResourceInfo adminObject : connector.adminObject) {
+                            createResource(adminObject);
+                        }
+                    } finally {
+                        Thread.currentThread().setContextClassLoader(oldClassLoader);
                     }
-                } finally {
-                    Thread.currentThread().setContextClassLoader(oldClassLoader);
                 }
-            }
 
-            final List<BeanContext> allDeployments = initEjbs(classLoader, appInfo, appContext, injections, new ArrayList<BeanContext>(), null);
+                final List<BeanContext> allDeployments = initEjbs(classLoader, appInfo, appContext, injections, new ArrayList<BeanContext>(), null);
 
-            if ("true".equalsIgnoreCase(SystemInstance.get()
-                .getProperty(PROPAGATE_APPLICATION_EXCEPTIONS,
-                    appInfo.properties.getProperty(PROPAGATE_APPLICATION_EXCEPTIONS, "false")))) {
-                propagateApplicationExceptions(appInfo, classLoader, allDeployments);
-            }
+                if ("true".equalsIgnoreCase(SystemInstance.get()
+                        .getProperty(PROPAGATE_APPLICATION_EXCEPTIONS,
+                                appInfo.properties.getProperty(PROPAGATE_APPLICATION_EXCEPTIONS, "false")))) {
+                    propagateApplicationExceptions(appInfo, classLoader, allDeployments);
+                }
 
-            if (shouldStartCdi(appInfo)) {
-                new CdiBuilder().build(appInfo, appContext, allDeployments);
-                ensureWebBeansContext(appContext);
-                appJndiContext.bind("app/BeanManager", appContext.getBeanManager());
-                appContext.getBindings().put("app/BeanManager", appContext.getBeanManager());
-            } else { // ensure we can reuse it in tomcat to remove OWB filters
-                appInfo.properties.setProperty("openejb.cdi.activated", "false");
-            }
+                if (shouldStartCdi(appInfo)) {
+                    new CdiBuilder().build(appInfo, appContext, allDeployments);
+                    ensureWebBeansContext(appContext);
+                    appJndiContext.bind("app/BeanManager", appContext.getBeanManager());
+                    appContext.getBindings().put("app/BeanManager", appContext.getBeanManager());
+                } else { // ensure we can reuse it in tomcat to remove OWB filters
+                    appInfo.properties.setProperty("openejb.cdi.activated", "false");
+                }
 
-            // now cdi is started we can try to bind real validator factory and validator
-            if (!isGeronimo) {
-                for (final Entry<String, LazyValidator> lazyValidator : lazyValidators.entrySet()) {
-                    final String id = lazyValidator.getKey();
-                    final ValidatorFactory factory = lazyValidatorFactories.get(lazyValidator.getKey()).getFactory();
-                    try {
-                        final String factoryName = VALIDATOR_FACTORY_NAMING_CONTEXT + id;
-                        containerSystemContext.unbind(factoryName);
-                        containerSystemContext.bind(factoryName, factory);
-
-                        final String validatoryName = VALIDATOR_NAMING_CONTEXT + id;
-                        try { // do it after factory cause of TCKs which expects validator to be created later
-                            final Validator val = lazyValidator.getValue().getValidator();
-                            containerSystemContext.unbind(validatoryName);
-                            containerSystemContext.bind(validatoryName, val);
+                // now cdi is started we can try to bind real validator factory and validator
+                if (!isGeronimo) {
+                    for (final Entry<String, LazyValidator> lazyValidator : lazyValidators.entrySet()) {
+                        final String id = lazyValidator.getKey();
+                        final ValidatorFactory factory = lazyValidatorFactories.get(lazyValidator.getKey()).getFactory();
+                        try {
+                            final String factoryName = VALIDATOR_FACTORY_NAMING_CONTEXT + id;
+                            containerSystemContext.unbind(factoryName);
+                            containerSystemContext.bind(factoryName, factory);
+
+                            final String validatoryName = VALIDATOR_NAMING_CONTEXT + id;
+                            try { // do it after factory cause of TCKs which expects validator to be created later
+                                final Validator val = lazyValidator.getValue().getValidator();
+                                containerSystemContext.unbind(validatoryName);
+                                containerSystemContext.bind(validatoryName, val);
+                            } catch (final Exception e) {
+                                logger.error(e.getMessage(), e);
+                            }
+                        } catch (final NameAlreadyBoundException e) {
+                            throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
                         } catch (final Exception e) {
-                            logger.error(e.getMessage(), e);
+                            throw new OpenEJBException(e);
                         }
-                    } catch (final NameAlreadyBoundException e) {
-                        throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
-                    } catch (final Exception e) {
-                        throw new OpenEJBException(e);
                     }
                 }
-            }
 
-            startEjbs(start, allDeployments);
+                startEjbs(start, allDeployments);
 
-            // App Client
-            for (final ClientInfo clientInfo : appInfo.clients) {
-                // determine the injections
-                final List<Injection> clientInjections = injectionBuilder.buildInjections(clientInfo.jndiEnc);
+                // App Client
+                for (final ClientInfo clientInfo : appInfo.clients) {
+                    // determine the injections
+                    final List<Injection> clientInjections = injectionBuilder.buildInjections(clientInfo.jndiEnc);
 
-                // build the enc
-                final JndiEncBuilder jndiEncBuilder = new JndiEncBuilder(clientInfo.jndiEnc, clientInjections, "Bean", clientInfo.moduleId, null, clientInfo.uniqueId, classLoader, new Properties());
-                // if there is at least a remote client classes
-                // or if there is no local client classes
-                // then, we can set the client flag
-                if (clientInfo.remoteClients.size() > 0 || clientInfo.localClients.size() == 0) {
-                    jndiEncBuilder.setClient(true);
+                    // build the enc
+                    final JndiEncBuilder jndiEncBuilder = new JndiEncBuilder(clientInfo.jndiEnc, clientInjections, "Bean", clientInfo.moduleId, null, clientInfo.uniqueId, classLoader, new Properties());
+                    // if there is at least a remote client classes
+                    // or if there is no local client classes
+                    // then, we can set the client flag
+                    if (clientInfo.remoteClients.size() > 0 || clientInfo.localClients.size() == 0) {
+                        jndiEncBuilder.setClient(true);
 
-                }
-                jndiEncBuilder.setUseCrossClassLoaderRef(false);
-                final Context context = jndiEncBuilder.build(JndiEncBuilder.JndiScope.comp);
+                    }
+                    jndiEncBuilder.setUseCrossClassLoaderRef(false);
+                    final Context context = jndiEncBuilder.build(JndiEncBuilder.JndiScope.comp);
 
-                //                Debug.printContext(context);
+                    //                Debug.printContext(context);
 
-                containerSystemContext.bind("openejb/client/" + clientInfo.moduleId, context);
+                    containerSystemContext.bind("openejb/client/" + clientInfo.moduleId, context);
 
-                if (clientInfo.path != null) {
-                    context.bind("info/path", clientInfo.path);
-                }
-                if (clientInfo.mainClass != null) {
-                    context.bind("info/mainClass", clientInfo.mainClass);
-                }
-                if (clientInfo.callbackHandler != null) {
-                    context.bind("info/callbackHandler", clientInfo.callbackHandler);
-                }
-                context.bind("info/injections", clientInjections);
+                    if (clientInfo.path != null) {
+                        context.bind("info/path", clientInfo.path);
+                    }
+                    if (clientInfo.mainClass != null) {
+                        context.bind("info/mainClass", clientInfo.mainClass);
+                    }
+                    if (clientInfo.callbackHandler != null) {
+                        context.bind("info/callbackHandler", clientInfo.callbackHandler);
+                    }
+                    context.bind("info/injections", clientInjections);
 
-                for (final String clientClassName : clientInfo.remoteClients) {
-                    containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
-                }
+                    for (final String clientClassName : clientInfo.remoteClients) {
+                        containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
+                    }
 
-                for (final String clientClassName : clientInfo.localClients) {
-                    containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
-                    logger.getChildLogger("client").info("createApplication.createLocalClient", clientClassName, clientInfo.moduleId);
+                    for (final String clientClassName : clientInfo.localClients) {
+                        containerSystemContext.bind("openejb/client/" + clientClassName, clientInfo.moduleId);
+                        logger.getChildLogger("client").info("createApplication.createLocalClient", clientClassName, clientInfo.moduleId);
+                    }
                 }
-            }
 
-            // WebApp
-            final SystemInstance systemInstance = SystemInstance.get();
+                // WebApp
+                final SystemInstance systemInstance = SystemInstance.get();
 
-            final WebAppBuilder webAppBuilder = systemInstance.getComponent(WebAppBuilder.class);
-            if (webAppBuilder != null) {
-                webAppBuilder.deployWebApps(appInfo, classLoader);
-            }
+                final WebAppBuilder webAppBuilder = systemInstance.getComponent(WebAppBuilder.class);
+                if (webAppBuilder != null) {
+                    webAppBuilder.deployWebApps(appInfo, classLoader);
+                }
 
-            if (start) {
-                final EjbResolver globalEjbResolver = systemInstance.getComponent(EjbResolver.class);
-                globalEjbResolver.addAll(appInfo.ejbJars);
-            }
+                if (start) {
+                    final EjbResolver globalEjbResolver = systemInstance.getComponent(EjbResolver.class);
+                    globalEjbResolver.addAll(appInfo.ejbJars);
+                }
 
-            // bind all global values on global context
-            bindGlobals(appContext.getBindings());
+                // bind all global values on global context
+                bindGlobals(appContext.getBindings());
 
-            validateCdiResourceProducers(appContext, appInfo);
+                validateCdiResourceProducers(appContext, appInfo);
 
-            // deploy MBeans
-            for (final String mbean : appInfo.mbeans) {
-                deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, appInfo.appId);
-            }
-            for (final EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
-                for (final String mbean : ejbJarInfo.mbeans) {
-                    deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, ejbJarInfo.moduleName);
+                // deploy MBeans
+                for (final String mbean : appInfo.mbeans) {
+                    deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, appInfo.appId);
                 }
-            }
-            for (final ConnectorInfo connectorInfo : appInfo.connectors) {
-                for (final String mbean : connectorInfo.mbeans) {
-                    deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, appInfo.appId + ".add-lib");
+                for (final EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
+                    for (final String mbean : ejbJarInfo.mbeans) {
+                        deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, ejbJarInfo.moduleName);
+                    }
+                }
+                for (final ConnectorInfo connectorInfo : appInfo.connectors) {
+                    for (final String mbean : connectorInfo.mbeans) {
+                        deployMBean(appContext.getWebBeansContext(), classLoader, mbean, appInfo.jmx, appInfo.appId + ".add-lib");
+                    }
                 }
-            }
 
-            postConstructResources(appInfo.resourceIds, classLoader, containerSystemContext, appContext);
-            
-            deployedApplications.put(appInfo.path, appInfo);
-            resumePersistentSchedulers(appContext);
+                postConstructResources(appInfo.resourceIds, classLoader, containerSystemContext, appContext);
 
-            systemInstance.fireEvent(new AssemblerAfterApplicationCreated(appInfo, appContext, allDeployments));
-            logger.info("createApplication.success", appInfo.path);
+                deployedApplications.put(appInfo.path, appInfo);
+                resumePersistentSchedulers(appContext);
 
-            return appContext;
-        } catch (final ValidationException | DeploymentException ve) {
-            throw ve;
-        } catch (final Throwable t) {
-            try {
-                destroyApplication(appInfo);
-            } catch (final Exception e1) {
-                logger.debug("createApplication.undeployFailed", e1, appInfo.path);
+                systemInstance.fireEvent(new AssemblerAfterApplicationCreated(appInfo, appContext, allDeployments));
+                logger.info("createApplication.success", appInfo.path);
+
+                return appContext;
+            } catch (final ValidationException | DeploymentException ve) {
+                throw ve;
+            } catch (final Throwable t) {
+                try {
+                    destroyApplication(appInfo);
+                } catch (final Exception e1) {
+                    logger.debug("createApplication.undeployFailed", e1, appInfo.path);
+                }
+                throw new OpenEJBException(messages.format("createApplication.failed", appInfo.path), t);
+            }
+        } finally {
+            // cleanup there as well by safety cause we have multiple deployment mode (embedded, tomcat...)
+            for (final WebAppInfo webApp : appInfo.webApps) {
+                appInfo.properties.remove(webApp);
             }
-            throw new OpenEJBException(messages.format("createApplication.failed", appInfo.path), t);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/1a3f66df/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
index 19837a6..c36b67d 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
@@ -832,6 +832,18 @@ public class ConfigurationFactory implements OpenEjbConfigurationFactory {
             final AppModule appModule = deploymentLoader.load(jarFile, null);
             final AppInfo appInfo = configureApplication(appModule);
 
+            // we need the finder for web scanning so push it to what sees TomcatWebAppBuilder, ie the info tree
+            // this is clean up in Assembler for safety and TomcatWebAppBuilder when used
+            if (!appModule.getWebModules().isEmpty()) {
+                for (final WebAppInfo info : appInfo.webApps) {
+                    for (final EjbModule ejbModule : appModule.getEjbModules()) {
+                        if (ejbModule.getModuleId().equals(info.moduleId) && ejbModule.getFinder() != null) {
+                            appInfo.properties.put(info, ejbModule);
+                        }
+                    }
+                }
+            }
+
             // TODO This is temporary -- we need to do this in AppInfoBuilder
             appInfo.paths.add(appInfo.path);
             appInfo.paths.add(jarFile.getAbsolutePath());

http://git-wip-us.apache.org/repos/asf/tomee/blob/1a3f66df/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
index 4756dfb..0368459 100644
--- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
@@ -446,138 +446,144 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
      */
     @Override
     public void deployWebApps(final AppInfo appInfo, final ClassLoader classLoader) throws Exception {
-        for (final WebAppInfo webApp : appInfo.webApps) {
-            // look for context.xml
-            final File war = new File(webApp.path);
-            InputStream contextXml = null;
-            URL contextXmlUrl = null;
-            if (war.isDirectory()) {
-                final File cXml = new File(war, Constants.ApplicationContextXml).getAbsoluteFile();
-                if (cXml.exists()) {
-                    contextXml = IO.read(cXml);
-                    contextXmlUrl = cXml.toURI().toURL();
-                    logger.info("using context file " + cXml.getAbsolutePath());
-                }
-            } else { // war
-                final JarFile warAsJar = new JarFile(war);
-                final JarEntry entry = warAsJar.getJarEntry(Constants.ApplicationContextXml);
-                if (entry != null) {
-                    contextXmlUrl = new URL("jar:" + war.getAbsoluteFile().toURI().toURL().toExternalForm() + "!/" + Constants.ApplicationContextXml);
-                    contextXml = warAsJar.getInputStream(entry);
+        try {
+            for (final WebAppInfo webApp : appInfo.webApps) {
+                // look for context.xml
+                final File war = new File(webApp.path);
+                InputStream contextXml = null;
+                URL contextXmlUrl = null;
+                if (war.isDirectory()) {
+                    final File cXml = new File(war, Constants.ApplicationContextXml).getAbsoluteFile();
+                    if (cXml.exists()) {
+                        contextXml = IO.read(cXml);
+                        contextXmlUrl = cXml.toURI().toURL();
+                        logger.info("using context file " + cXml.getAbsolutePath());
+                    }
+                } else { // war
+                    final JarFile warAsJar = new JarFile(war);
+                    final JarEntry entry = warAsJar.getJarEntry(Constants.ApplicationContextXml);
+                    if (entry != null) {
+                        contextXmlUrl = new URL("jar:" + war.getAbsoluteFile().toURI().toURL().toExternalForm() + "!/" + Constants.ApplicationContextXml);
+                        contextXml = warAsJar.getInputStream(entry);
+                    }
                 }
-            }
 
-            if (isAlreadyDeployed(appInfo, webApp)) {
-                continue;
-            }
+                if (isAlreadyDeployed(appInfo, webApp)) {
+                    continue;
+                }
 
-            StandardContext standardContext;
-            {
-                final ClassLoader containerLoader = Helper.get();
-                final Host host = hosts.getDefault();
-                if (StandardHost.class.isInstance(host) && !StandardContext.class.getName().equals(StandardHost.class.cast(host).getContextClass())) {
-                    try {
-                        standardContext = StandardContext.class.cast(containerLoader.loadClass(StandardHost.class.cast(host).getContextClass()).newInstance());
-                    } catch (final Throwable th) {
-                        logger.warning("Can't use context class specified, using default StandardContext", th);
+                StandardContext standardContext;
+                {
+                    final ClassLoader containerLoader = Helper.get();
+                    final Host host = hosts.getDefault();
+                    if (StandardHost.class.isInstance(host) && !StandardContext.class.getName().equals(StandardHost.class.cast(host).getContextClass())) {
+                        try {
+                            standardContext = StandardContext.class.cast(containerLoader.loadClass(StandardHost.class.cast(host).getContextClass()).newInstance());
+                        } catch (final Throwable th) {
+                            logger.warning("Can't use context class specified, using default StandardContext", th);
+                            standardContext = new StandardContext();
+                        }
+                    } else {
                         standardContext = new StandardContext();
                     }
-                } else {
-                    standardContext = new StandardContext();
+                    // should be optional but in maven parent is app loader and not maven loader which is the real parent
+                    final ClassLoader currentParent = standardContext.getParentClassLoader();
+                    if (currentParent == null || isParent(currentParent, containerLoader)) {
+                        standardContext.setParentClassLoader(containerLoader);
+                    }
                 }
-                // should be optional but in maven parent is app loader and not maven loader which is the real parent
-                final ClassLoader currentParent = standardContext.getParentClassLoader();
-                if (currentParent == null || isParent(currentParent, containerLoader)) {
-                    standardContext.setParentClassLoader(containerLoader);
+                if (contextXml != null) {
+                    standardContext.setConfigFile(contextXmlUrl);
                 }
-            }
-            if (contextXml != null) {
-                standardContext.setConfigFile(contextXmlUrl);
-            }
-
-            if (standardContext.getPath() != null) {
-                webApp.contextRoot = standardContext.getPath();
-            }
-            if (webApp.contextRoot.startsWith("/") || webApp.contextRoot.startsWith(File.separator)) {
-                webApp.contextRoot = webApp.contextRoot.substring(1);
-            }
-            if (webApp.contextRoot.startsWith(File.separator)) {
-                webApp.contextRoot = webApp.contextRoot.replaceFirst(File.separator, "");
-            }
 
-            // /!\ take care, StandardContext default host = "_" and not null or localhost
-            final String hostname = Contexts.getHostname(standardContext);
-            if (hostname != null && !"_".equals(hostname)) {
-                webApp.host = hostname;
-            }
-
-            final ApplicationParameter appParam = new ApplicationParameter();
-            appParam.setName(OPENEJB_WEBAPP_MODULE_ID);
-            appParam.setValue(webApp.moduleId);
-            standardContext.addApplicationParameter(appParam);
-
-            if (!isAlreadyDeployed(appInfo, webApp)) {
-                if (standardContext.getPath() == null) {
-                    if (webApp.contextRoot != null && webApp.contextRoot.startsWith("/")) {
-                        standardContext.setPath(webApp.contextRoot);
-                    } else if (isRoot(webApp.contextRoot)) {
-                        standardContext.setPath("");
-                    } else {
-                        standardContext.setPath("/" + webApp.contextRoot);
-                    }
-                }
-                if (standardContext.getDocBase() == null) {
-                    standardContext.setDocBase(webApp.path);
+                if (standardContext.getPath() != null) {
+                    webApp.contextRoot = standardContext.getPath();
                 }
-                if (standardContext.getDocBase() != null && standardContext.getDocBase().endsWith(".war")) {
-                    DeploymentLoader.unpack(new File(standardContext.getDocBase()));
-                    if (standardContext.getPath().endsWith(".war")) {
-                        standardContext.setPath(removeFirstSlashAndWar("/" + standardContext.getPath()));
-                        standardContext.setName(standardContext.getPath());
-                        webApp.contextRoot = standardContext.getPath();
-                    }
-                    standardContext.setDocBase(standardContext.getDocBase().substring(0, standardContext.getDocBase().length() - 4));
+                if (webApp.contextRoot.startsWith("/") || webApp.contextRoot.startsWith(File.separator)) {
+                    webApp.contextRoot = webApp.contextRoot.substring(1);
                 }
-                if (isRoot(standardContext.getName())) {
-                    standardContext.setName("");
-                    webApp.contextRoot = "";
+                if (webApp.contextRoot.startsWith(File.separator)) {
+                    webApp.contextRoot = webApp.contextRoot.replaceFirst(File.separator, "");
                 }
 
-                if (isAlreadyDeployed(appInfo, webApp)) { // possible because of the previous renaming
-                    continue;
+                // /!\ take care, StandardContext default host = "_" and not null or localhost
+                final String hostname = Contexts.getHostname(standardContext);
+                if (hostname != null && !"_".equals(hostname)) {
+                    webApp.host = hostname;
                 }
 
-                // add classloader which is an URLClassLoader created by openejb
-                // {@see Assembler}
-                //
-                // we add it as parent classloader since we scanned classes with this classloader
-                // that's why we force delegate to true.
-                //
-                // However since this classloader and the webappclassloader will have a lot
-                // of common classes/resources we have to avoid duplicated resources
-                // so we contribute a custom loader.
-                //
-                // Note: the line standardContext.getLoader().setDelegate(true);
-                // could be hardcoded in the custom loader
-                // but here we have all the classloading logic
-                if (classLoader != null) {
-                    standardContext.setParentClassLoader(classLoader);
-                    standardContext.setDelegate(true);
-                }
+                final ApplicationParameter appParam = new ApplicationParameter();
+                appParam.setName(OPENEJB_WEBAPP_MODULE_ID);
+                appParam.setValue(webApp.moduleId);
+                standardContext.addApplicationParameter(appParam);
+
+                if (!isAlreadyDeployed(appInfo, webApp)) {
+                    if (standardContext.getPath() == null) {
+                        if (webApp.contextRoot != null && webApp.contextRoot.startsWith("/")) {
+                            standardContext.setPath(webApp.contextRoot);
+                        } else if (isRoot(webApp.contextRoot)) {
+                            standardContext.setPath("");
+                        } else {
+                            standardContext.setPath("/" + webApp.contextRoot);
+                        }
+                    }
+                    if (standardContext.getDocBase() == null) {
+                        standardContext.setDocBase(webApp.path);
+                    }
+                    if (standardContext.getDocBase() != null && standardContext.getDocBase().endsWith(".war")) {
+                        DeploymentLoader.unpack(new File(standardContext.getDocBase()));
+                        if (standardContext.getPath().endsWith(".war")) {
+                            standardContext.setPath(removeFirstSlashAndWar("/" + standardContext.getPath()));
+                            standardContext.setName(standardContext.getPath());
+                            webApp.contextRoot = standardContext.getPath();
+                        }
+                        standardContext.setDocBase(standardContext.getDocBase().substring(0, standardContext.getDocBase().length() - 4));
+                    }
+                    if (isRoot(standardContext.getName())) {
+                        standardContext.setName("");
+                        webApp.contextRoot = "";
+                    }
 
-                String host = webApp.host;
-                if (host == null) {
-                    host = hosts.getDefaultHost();
-                    logger.info("using default host: " + host);
-                }
+                    if (isAlreadyDeployed(appInfo, webApp)) { // possible because of the previous renaming
+                        continue;
+                    }
+
+                    // add classloader which is an URLClassLoader created by openejb
+                    // {@see Assembler}
+                    //
+                    // we add it as parent classloader since we scanned classes with this classloader
+                    // that's why we force delegate to true.
+                    //
+                    // However since this classloader and the webappclassloader will have a lot
+                    // of common classes/resources we have to avoid duplicated resources
+                    // so we contribute a custom loader.
+                    //
+                    // Note: the line standardContext.getLoader().setDelegate(true);
+                    // could be hardcoded in the custom loader
+                    // but here we have all the classloading logic
+                    if (classLoader != null) {
+                        standardContext.setParentClassLoader(classLoader);
+                        standardContext.setDelegate(true);
+                    }
+
+                    String host = webApp.host;
+                    if (host == null) {
+                        host = hosts.getDefaultHost();
+                        logger.info("using default host: " + host);
+                    }
 
-                if (classLoader != null) {
-                    appInfo.autoDeploy = false;
-                    deployWar(standardContext, host, appInfo);
-                } else { // force a normal deployment with lazy building of AppInfo
-                    deployWar(standardContext, host, null);
+                    if (classLoader != null) {
+                        appInfo.autoDeploy = false;
+                        deployWar(standardContext, host, appInfo);
+                    } else { // force a normal deployment with lazy building of AppInfo
+                        deployWar(standardContext, host, null);
+                    }
                 }
             }
+        } finally { // cleanup temp var passing
+            for (final WebAppInfo webApp : appInfo.webApps) {
+                appInfo.properties.remove(webApp);
+            }
         }
     }
 
@@ -616,6 +622,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
                 final ContextInfo contextInfo = addContextInfo(host, standardContext);
                 contextInfo.appInfo = info;
                 contextInfo.deployer = deployer;
+                contextInfo.module = extractModule(standardContext, info);
             }
 
             deployer.manageApp(standardContext);
@@ -626,6 +633,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
                     final ContextInfo contextInfo = addContextInfo(host, standardContext);
                     contextInfo.appInfo = info;
                     contextInfo.host = theHost;
+                    contextInfo.module = extractModule(standardContext, info);
                 }
 
                 theHost.addChild(standardContext);
@@ -633,6 +641,16 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
         }
     }
 
+    private EjbModule extractModule(final StandardContext standardContext, final AppInfo appInfo) {
+        for (final WebAppInfo app : appInfo.webApps) {
+            if (app.path != null && warPath(standardContext).equals(rootPath(new File(app.path)))) {
+                // see org.apache.openejb.config.ConfigurationFactory.configureApplication(java.io.File)
+                return EjbModule.class.cast(appInfo.properties.remove(app));
+            }
+        }
+        return null;
+    }
+
     public synchronized ContextInfo standaAloneWebAppInfo(final File file) {
         for (final ContextInfo info : infos.values()) {
             if (info.appInfo != null && info.appInfo.webAppAlone
@@ -1112,6 +1130,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
 
         if (contextInfo == null) {
             final AppModule appModule = loadApplication(standardContext);
+            appModule.getProperties().put("loader.from", "tomcat");
 
             if (standardContext.getNamingResources() instanceof OpenEJBNamingResource) {
                 final Collection<String> importedNames = new ArrayList<>(); // we can get the same resource twice as in tomcat
@@ -1235,6 +1254,12 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
             }
         } else {
             contextInfo.standardContext = standardContext;
+            if (contextInfo.module != null && contextInfo.module.getFinder() != null) { // TODO: make it more explicit or less hacky not using properties
+                final OpenEJBContextConfig openEJBContextConfig = findOpenEJBContextConfig(standardContext);
+                if (openEJBContextConfig != null) {
+                    openEJBContextConfig.finder(contextInfo.module.getFinder(), contextInfo.module.getClassLoader());
+                }
+            }
         }
 
         final String id = getId(standardContext);
@@ -1392,13 +1417,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
     }
 
     public void setFinderOnContextConfig(final StandardContext standardContext, final AppModule appModule) {
-        OpenEJBContextConfig openEJBContextConfig = null;
-        for (final LifecycleListener listener : standardContext.findLifecycleListeners()) {
-            if (OpenEJBContextConfig.class.isInstance(listener)) {
-                openEJBContextConfig = OpenEJBContextConfig.class.cast(listener);
-                break;
-            }
-        }
+        final OpenEJBContextConfig openEJBContextConfig = findOpenEJBContextConfig(standardContext);
         if (openEJBContextConfig != null) {
             for (final EjbModule ejbModule : appModule.getEjbModules()) {
                 if (ejbModule.getFile() != null && warPath(standardContext).equals(rootPath(ejbModule.getFile()))) {
@@ -1409,6 +1428,17 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
         }
     }
 
+    private OpenEJBContextConfig findOpenEJBContextConfig(StandardContext standardContext) {
+        OpenEJBContextConfig openEJBContextConfig = null;
+        for (final LifecycleListener listener : standardContext.findLifecycleListeners()) {
+            if (OpenEJBContextConfig.class.isInstance(listener)) {
+                openEJBContextConfig = OpenEJBContextConfig.class.cast(listener);
+                break;
+            }
+        }
+        return openEJBContextConfig;
+    }
+
     private static File rootPath(final File file) {
         if (file.isDirectory() && file.getName().equals("classes") && file.getParentFile() != null && file.getParentFile().getName().equals("WEB-INF")) {
             final File parentFile = file.getParentFile().getParentFile();
@@ -1583,6 +1613,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
 
         // if appInfo is null this is a failed deployment... just ignore
         final ContextInfo contextInfo = getContextInfo(standardContext);
+        contextInfo.module = null; // shouldnt be there after startup (actually we shouldnt need it from info tree but our scanning does)
         if (contextInfo != null && contextInfo.appInfo == null) {
             return;
         } else if (contextInfo == null) { // openejb webapp loaded from the LoaderServlet
@@ -2475,6 +2506,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
         public StandardContext standardContext;
         public HostConfig deployer;
         public Host host;
+        public EjbModule module; // just during startup
         public String version;
         public Collection<String> resourceNames = Collections.emptyList();