Author: rmannibucau
Date: Sun Sep  7 13:49:52 2014
New Revision: 1623012

URL: http://svn.apache.org/r1623012
Log:
TOMEE-1330 allow to scan container for wars + TOMEE-1339 try static resources 
first for JAXRS + TOMEE-1329 supporting empty line in jars.txt + TOMEE-1297 
@Jars for AppComposer + TOMEE-1325 suporting interfaces for synamic subclassing 
+ TOMEE-1296 typo to get mbean server in OpenEJBServerPlatform + TOMEE-1295 
support openjpa.EntityManagerFactoryPool + OPENEJB-2100 correct reset of 
openejb classloader in openejb cli + respect force reset logs property + new 
finder API + TOMEE-1334 NPE in LazyRealm + CDI @Startup support -- backports 
from trunk

Added:
    
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/
    
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/AvoidConflictTest.java
    
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/TheResource.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/testing/Jars.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/test/java/org/apache/openejb/dyni/LocalButDynamicSingletonTest.java
Modified:
    
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBArchiveProcessor.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/classloader/ProvisioningClassLoaderConfigurer.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/FinderFactory.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/core/TempClassLoader.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/dyni/DynamicSubclass.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/JuliLogStreamFactory.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/util/proxy/DynamicProxyImplFactory.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-jee/src/main/java/org/apache/openejb/jee/Beans.java
    
tomee/tomee/branches/tomee-1.7.x/container/openejb-jpa-integration/src/main/java/org/apache/openejb/jpa/integration/eclipselink/OpenEJBServerPlatform.java
    
tomee/tomee/branches/tomee-1.7.x/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/AbstractTomEEMojo.java
    tomee/tomee/branches/tomee-1.7.x/pom.xml
    
tomee/tomee/branches/tomee-1.7.x/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java
    
tomee/tomee/branches/tomee-1.7.x/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
    
tomee/tomee/branches/tomee-1.7.x/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/realm/LazyRealm.java

Modified: 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBArchiveProcessor.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBArchiveProcessor.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBArchiveProcessor.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBArchiveProcessor.java
 Sun Sep  7 13:49:52 2014
@@ -34,7 +34,6 @@ import org.apache.openejb.jee.oejb3.EjbD
 import org.apache.openejb.jee.oejb3.OpenejbJar;
 import org.apache.openejb.loader.IO;
 import org.apache.openejb.util.classloader.URLClassLoaderFirst;
-import org.apache.xbean.finder.AnnotationFinder;
 import org.apache.xbean.finder.archive.ClassesArchive;
 import org.apache.xbean.finder.archive.CompositeArchive;
 import org.apache.xbean.finder.archive.FilteredArchive;
@@ -200,10 +199,11 @@ public class OpenEJBArchiveProcessor {
 
         final org.apache.xbean.finder.archive.Archive finderArchive = 
finderArchive(beansXml, archive, tempClassLoader, additionalPaths);
 
-        ejbModule.setFinder(new FinderFactory.ModuleLimitedFinder(new 
AnnotationFinder(finderArchive)));
+        ejbModule.setFinder(new FinderFactory.ModuleLimitedFinder(new 
FinderFactory.OpenEJBAnnotationFinder(finderArchive)));
         if (appModule.isWebapp()) { // war
             
appModule.getWebModules().iterator().next().setFinder(ejbModule.getFinder());
         }
+
         appModule.getEjbModules().add(ejbModule);
 
         {

Added: 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/AvoidConflictTest.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/AvoidConflictTest.java?rev=1623012&view=auto
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/AvoidConflictTest.java
 (added)
+++ 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/AvoidConflictTest.java
 Sun Sep  7 13:49:52 2014
@@ -0,0 +1,56 @@
+/*
+ * 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.arquillian.tests.jaxrs.staticresources;
+
+import org.apache.ziplock.IO;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class AvoidConflictTest {
+    @Deployment(testable = false)
+    public static Archive<?> war() {
+        return ShrinkWrap.create(WebArchive.class, "app.war")
+                .addClass(TheResource.class)
+                .addAsWebResource(new StringAsset("static"), "index.html");
+    }
+
+    @ArquillianResource
+    private URL url;
+
+    @Test
+    public void jaxrs() throws IOException {
+        assertEquals("resource", IO.slurp(new URL(url.toExternalForm() + 
"the")));
+    }
+
+    @Test
+    public void staticResource() throws IOException {
+        assertEquals("static", IO.slurp(url));
+    }
+}

Added: 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/TheResource.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/TheResource.java?rev=1623012&view=auto
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/TheResource.java
 (added)
+++ 
tomee/tomee/branches/tomee-1.7.x/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/staticresources/TheResource.java
 Sun Sep  7 13:49:52 2014
@@ -0,0 +1,29 @@
+/*
+ * 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.arquillian.tests.jaxrs.staticresources;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+@Path("/")
+public class TheResource {
+    @GET
+    @Path("the")
+    public String get() {
+        return "resource";
+    }
+}
\ No newline at end of file

Modified: 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
 Sun Sep  7 13:49:52 2014
@@ -32,7 +32,6 @@ import org.apache.openejb.core.intercept
 import org.apache.openejb.core.ivm.ContextHandler;
 import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
 import org.apache.openejb.core.timer.EjbTimerService;
-import org.apache.openejb.core.timer.EjbTimerServiceImpl;
 import org.apache.openejb.core.transaction.EjbTransactionUtil;
 import org.apache.openejb.core.transaction.TransactionPolicy;
 import org.apache.openejb.core.transaction.TransactionPolicyFactory;
@@ -101,7 +100,6 @@ public class BeanContext extends Deploym
     public static final String USER_INTERCEPTOR_KEY = 
"org.apache.openejb.default.system.interceptors";
     public static final String USER_INTERCEPTOR_SEPARATOR = ",| |;";
 
-    private boolean isPassivatingScope = true;
     private ConstructorInjectionBean<Object> constructorInjectionBean;
 
     public boolean isDynamicallyImplemented() {
@@ -1756,7 +1754,7 @@ public class BeanContext extends Deploym
     public boolean isPassivatingScope() {
         final CdiEjbBean<?> bean = get(CdiEjbBean.class);
         if (bean == null) {
-            return isPassivatingScope;
+            return true;
         }
 
         if (ConversationScoped.class == bean.getScope()) {
@@ -1767,12 +1765,12 @@ public class BeanContext extends Deploym
             }
         }
 
-        return isPassivatingScope;
+        return true;
     }
 
     public void stop() {
-        if (ejbTimerService != null && ejbTimerService instanceof 
EjbTimerServiceImpl) {
-            ((EjbTimerServiceImpl) ejbTimerService).stop();
+        if (ejbTimerService != null) {
+            ejbTimerService.stop();
         }
     }
 

Modified: 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
 Sun Sep  7 13:49:52 2014
@@ -29,6 +29,7 @@ import java.util.concurrent.Callable;
 
 public class EntityManagerFactoryCallable implements 
Callable<EntityManagerFactory> {
     public static final String OPENEJB_JPA_INIT_ENTITYMANAGER = 
"openejb.jpa.init-entitymanager";
+    public static final String OPENJPA_ENTITY_MANAGER_FACTORY_POOL = 
"openjpa.EntityManagerFactoryPool";
 
     private final String persistenceProviderClassName;
     private final PersistenceUnitInfoImpl unitInfo;
@@ -53,11 +54,14 @@ public class EntityManagerFactoryCallabl
             if (!ValidationMode.NONE.equals(unitInfo.getValidationMode())) {
                 properties.put("javax.persistence.validator.ValidatorFactory", 
new ValidatorFactoryWrapper());
             }
+
+            customizeProperties(properties);
+
             final EntityManagerFactory emf = 
persistenceProvider.createContainerEntityManagerFactory(unitInfo, properties);
 
             if (unitInfo.getProperties() != null
-                && 
"true".equalsIgnoreCase(unitInfo.getProperties().getProperty(OPENEJB_JPA_INIT_ENTITYMANAGER))
-                || 
SystemInstance.get().getOptions().get(OPENEJB_JPA_INIT_ENTITYMANAGER, false)) {
+                    && 
"true".equalsIgnoreCase(unitInfo.getProperties().getProperty(OPENEJB_JPA_INIT_ENTITYMANAGER))
+                    || 
SystemInstance.get().getOptions().get(OPENEJB_JPA_INIT_ENTITYMANAGER, false)) {
                 emf.createEntityManager().close();
             }
 
@@ -75,6 +79,13 @@ public class EntityManagerFactoryCallabl
         }
     }
 
+    private void customizeProperties(final Map<String, Object> properties) {
+        final String pool = 
SystemInstance.get().getProperty(OPENJPA_ENTITY_MANAGER_FACTORY_POOL);
+        if (pool != null) {
+            properties.put(OPENJPA_ENTITY_MANAGER_FACTORY_POOL, pool);
+        }
+    }
+
     public PersistenceUnitInfoImpl getUnitInfo() {
         return unitInfo;
     }

Modified: 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/classloader/ProvisioningClassLoaderConfigurer.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/classloader/ProvisioningClassLoaderConfigurer.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/classloader/ProvisioningClassLoaderConfigurer.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/classloader/ProvisioningClassLoaderConfigurer.java
 Sun Sep  7 13:49:52 2014
@@ -79,7 +79,7 @@ public class ProvisioningClassLoaderConf
             String line;
             while ((line = reader.readLine()) != null) {
                 line = 
PropertyPlaceHolderHelper.SUBSTITUTOR.replace(line.trim());
-                if (line.startsWith("#")) {
+                if (line.startsWith("#") || line.isEmpty()) {
                     continue;
                 }
 

Modified: 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
 Sun Sep  7 13:49:52 2014
@@ -124,6 +124,7 @@ import org.apache.openejb.util.Join;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.SuperProperties;
+import org.apache.openejb.util.URLs;
 import org.apache.openejb.util.proxy.DynamicProxyImplFactory;
 import org.apache.xbean.finder.Annotated;
 import org.apache.xbean.finder.AnnotationFinder;
@@ -182,8 +183,6 @@ import javax.ejb.TransactionAttribute;
 import javax.ejb.TransactionAttributeType;
 import javax.ejb.TransactionManagement;
 import javax.ejb.TransactionManagementType;
-import javax.enterprise.inject.Specializes;
-import javax.enterprise.inject.spi.Extension;
 import javax.interceptor.ExcludeClassInterceptors;
 import javax.interceptor.ExcludeDefaultInterceptors;
 import javax.interceptor.Interceptors;
@@ -238,6 +237,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -245,6 +245,8 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.TreeSet;
 
+import static java.util.Arrays.asList;
+
 /**
  * @version $Rev$ $Date$
  */
@@ -258,41 +260,41 @@ public class AnnotationDeployer implemen
     private static final ThreadLocal<DeploymentModule> currentModule = new 
ThreadLocal<DeploymentModule>();
     private static final Set<String> lookupMissing = new HashSet<String>(2);
     private static final String[] JSF_CLASSES = new String[]{
-        "javax.faces.application.ResourceDependencies",
-        "javax.faces.application.ResourceDependency",
-        "javax.faces.bean.ApplicationScoped",
-        "javax.faces.bean.CustomScoped",
-        "javax.faces.bean.ManagedBean",
-        "javax.faces.bean.ManagedProperty",
-        "javax.faces.bean.NoneScoped",
-        "javax.faces.bean.ReferencedBean",
-        "javax.faces.bean.RequestScoped",
-        "javax.faces.bean.SessionScoped",
-        "javax.faces.bean.ViewScoped",
-        "javax.faces.component.FacesComponent",
-        "javax.faces.component.UIComponent",
-        "javax.faces.convert.Converter",
-        "javax.faces.convert.FacesConverter",
-        "javax.faces.event.ListenerFor",
-        "javax.faces.event.ListenersFor",
-        "javax.faces.event.NamedEvent",
-        "javax.faces.render.FacesBehaviorRenderer",
-        "javax.faces.render.FacesRenderer",
-        "javax.faces.render.Renderer",
-        "javax.faces.validator.FacesValidator",
-        "javax.faces.validator.Validator"
+            "javax.faces.application.ResourceDependencies",
+            "javax.faces.application.ResourceDependency",
+            "javax.faces.bean.ApplicationScoped",
+            "javax.faces.bean.CustomScoped",
+            "javax.faces.bean.ManagedBean",
+            "javax.faces.bean.ManagedProperty",
+            "javax.faces.bean.NoneScoped",
+            "javax.faces.bean.ReferencedBean",
+            "javax.faces.bean.RequestScoped",
+            "javax.faces.bean.SessionScoped",
+            "javax.faces.bean.ViewScoped",
+            "javax.faces.component.FacesComponent",
+            "javax.faces.component.UIComponent",
+            "javax.faces.convert.Converter",
+            "javax.faces.convert.FacesConverter",
+            "javax.faces.event.ListenerFor",
+            "javax.faces.event.ListenersFor",
+            "javax.faces.event.NamedEvent",
+            "javax.faces.render.FacesBehaviorRenderer",
+            "javax.faces.render.FacesRenderer",
+            "javax.faces.render.Renderer",
+            "javax.faces.validator.FacesValidator",
+            "javax.faces.validator.Validator"
     };
 
     private static final String[] WEB_CLASSES = new String[]{
-        // Servlet 3.0
-        "javax.servlet.annotation.WebServlet",
-        "javax.servlet.annotation.WebFilter",
-        "javax.servlet.annotation.WebListener",
-
-        // WebSocket 1.0 (since Tomcat 7.0.47)
-        "javax.websocket.server.ServerEndpoint",
-        "javax.websocket.server.ServerApplicationConfig",
-        "javax.websocket.Endpoint"
+            // Servlet 3.0
+            "javax.servlet.annotation.WebServlet",
+            "javax.servlet.annotation.WebFilter",
+            "javax.servlet.annotation.WebListener",
+
+            // WebSocket 1.0 (since Tomcat 7.0.47)
+            "javax.websocket.server.ServerEndpoint",
+            "javax.websocket.server.ServerApplicationConfig",
+            "javax.websocket.Endpoint"
     };
 
     private static final Collection<String> API_CLASSES = new 
ArrayList<String>(WEB_CLASSES.length + JSF_CLASSES.length);
@@ -303,31 +305,31 @@ public class AnnotationDeployer implemen
     }
 
     public static final Set<String> knownResourceEnvTypes = new 
TreeSet<String>(Arrays.asList(
-        "javax.ejb.EJBContext",
-        "javax.ejb.SessionContext",
-        "javax.ejb.EntityContext",
-        "javax.ejb.MessageDrivenContext",
-        "javax.transaction.UserTransaction",
-        "javax.jms.Queue",
-        "javax.jms.Topic",
-        "javax.xml.ws.WebServiceContext",
-        "javax.ejb.TimerService",
-        "javax.enterprise.inject.spi.BeanManager",
-        "javax.validation.Validator",
-        "javax.validation.ValidatorFactory"
+            "javax.ejb.EJBContext",
+            "javax.ejb.SessionContext",
+            "javax.ejb.EntityContext",
+            "javax.ejb.MessageDrivenContext",
+            "javax.transaction.UserTransaction",
+            "javax.jms.Queue",
+            "javax.jms.Topic",
+            "javax.xml.ws.WebServiceContext",
+            "javax.ejb.TimerService",
+            "javax.enterprise.inject.spi.BeanManager",
+            "javax.validation.Validator",
+            "javax.validation.ValidatorFactory"
     ));
 
     public static final Set<String> knownEnvironmentEntries = new 
TreeSet<String>(Arrays.asList(
-        "boolean", "java.lang.Boolean",
-        "char", "java.lang.Character",
-        "byte", "java.lang.Byte",
-        "short", "java.lang.Short",
-        "int", "java.lang.Integer",
-        "long", "java.lang.Long",
-        "float", "java.lang.Float",
-        "double", "java.lang.Double",
-        "java.lang.String",
-        "java.lang.Class"
+            "boolean", "java.lang.Boolean",
+            "char", "java.lang.Character",
+            "byte", "java.lang.Byte",
+            "short", "java.lang.Short",
+            "int", "java.lang.Integer",
+            "long", "java.lang.Long",
+            "float", "java.lang.Float",
+            "double", "java.lang.Double",
+            "java.lang.String",
+            "java.lang.Class"
     ));
 
     private final DiscoverAnnotatedBeans discoverAnnotatedBeans;
@@ -1296,41 +1298,7 @@ public class AnnotationDeployer implemen
 
                 if (beans != null) {
                     managedClasses = beans.getManagedClasses();
-                    final List<String> classNames = getBeanClasses(finder);
-
-                    final Set<String> notLoadedClasses = new TreeSet<String>();
-                    for (final String rawClassName : classNames) {
-                        final String className = realClassName(rawClassName);
-                        try {
-                            final ClassLoader loader = 
ejbModule.getClassLoader();
-                            final Class<?> clazz = loader.loadClass(className);
-
-                            // The following can NOT be beans in CDI
-
-                            // 1. Non-static inner classes
-                            if (clazz.getEnclosingClass() != null && 
!Modifier.isStatic(clazz.getModifiers())) {
-                                continue;
-                            }
-//
-//                            // 2. Abstract classes (unless they are an 
@Decorator)
-//                            if (Modifier.isAbstract(clazz.getModifiers()) && 
!clazz.isAnnotationPresent(javax.decorator.Decorator.class)) continue;
-//
-                            // 3. Implementations of Extension
-                            if (Extension.class.isAssignableFrom(clazz)) {
-                                continue;
-                            }
-
-                            managedClasses.add(className);
-                        } catch (final ClassNotFoundException e) {
-                            notLoadedClasses.add(rawClassName);
-                        } catch (final NoClassDefFoundError e) {
-                            // no-op
-                        }
-                    }
-
-                    if (!notLoadedClasses.isEmpty()) { // don't log in info or 
warning since not 100% JavaEE/CDI libs will break the whole logs
-                        logger.debug("Some classes can't be loaded: " + 
Join.join("\n", notLoadedClasses.toArray(new String[notLoadedClasses.size()])));
-                    }
+                    managedClasses.addAll(getBeanClasses(finder));
 
                     // passing jar location to be able to manage maven 
classes/test-classes which have the same moduleId
                     String id = ejbModule.getModuleId();
@@ -1344,13 +1312,19 @@ public class AnnotationDeployer implemen
                     final org.apache.openejb.jee.ManagedBean managedBean = new 
CompManagedBean(name, BeanContext.Comp.class);
                     managedBean.setTransactionType(TransactionType.BEAN);
                     ejbModule.getEjbJar().addEnterpriseBean(managedBean);
+
+                    if 
("true".equals(SystemInstance.get().getProperty("openejb.cdi.support.@Startup", 
"true"))) {
+                        final List<Annotated<Class<?>>> forceStart = 
finder.findMetaAnnotatedClasses(Startup.class);
+                        final List<String> startupBeans = 
beans.getStartupBeans();
+                        for (final Annotated<Class<?>> clazz : forceStart) {
+                            startupBeans.add(clazz.get().getName());
+                        }
+                    }
                 } else {
-                    managedClasses = new ArrayList<String>();
+                    managedClasses = new LinkedList<String>();
                 }
             }
 
-            final Set<Class<?>> specializingClasses = new HashSet<Class<?>>();
-
 
             // Fill in default sessionType for xml declared EJBs
             for (final EnterpriseBean bean : 
ejbModule.getEjbJar().getEnterpriseBeans()) {
@@ -1393,11 +1367,6 @@ public class AnnotationDeployer implemen
 
             final EjbJar ejbJar = ejbModule.getEjbJar();
             for (final Annotated<Class<?>> beanClass : 
finder.findMetaAnnotatedClasses(Singleton.class)) {
-
-                if (beanClass.isAnnotationPresent(Specializes.class)) {
-                    specializingClasses.add(beanClass.get());
-                }
-
                 final Singleton singleton = 
beanClass.getAnnotation(Singleton.class);
                 final String ejbName = getEjbName(singleton, beanClass.get());
 
@@ -1425,11 +1394,6 @@ public class AnnotationDeployer implemen
             }
 
             for (final Annotated<Class<?>> beanClass : 
finder.findMetaAnnotatedClasses(Stateless.class)) {
-
-                if (beanClass.isAnnotationPresent(Specializes.class)) {
-                    specializingClasses.add(beanClass.get());
-                }
-
                 final Stateless stateless = 
beanClass.getAnnotation(Stateless.class);
                 final String ejbName = getEjbName(stateless, beanClass.get());
 
@@ -1464,11 +1428,6 @@ public class AnnotationDeployer implemen
             // Anyway.. the qualifiers aren't getting inherited, so we need to 
fix that
 
             for (final Annotated<Class<?>> beanClass : 
finder.findMetaAnnotatedClasses(Stateful.class)) {
-
-                if (beanClass.isAnnotationPresent(Specializes.class)) {
-                    specializingClasses.add(beanClass.get());
-                }
-
                 final Stateful stateful = 
beanClass.getAnnotation(Stateful.class);
                 final String ejbName = getEjbName(stateful, beanClass.get());
 
@@ -1496,11 +1455,6 @@ public class AnnotationDeployer implemen
             }
 
             for (final Annotated<Class<?>> beanClass : 
finder.findMetaAnnotatedClasses(ManagedBean.class)) {
-
-                if (beanClass.isAnnotationPresent(Specializes.class)) {
-                    specializingClasses.add(beanClass.get());
-                }
-
                 final ManagedBean managed = 
beanClass.getAnnotation(ManagedBean.class);
                 final String ejbName = getEjbName(managed, beanClass.get());
 
@@ -1531,11 +1485,6 @@ public class AnnotationDeployer implemen
             }
 
             for (final Annotated<Class<?>> beanClass : 
finder.findMetaAnnotatedClasses(MessageDriven.class)) {
-
-                if (beanClass.isAnnotationPresent(Specializes.class)) {
-                    specializingClasses.add(beanClass.get());
-                }
-
                 final MessageDriven mdb = 
beanClass.getAnnotation(MessageDriven.class);
                 final String ejbName = getEjbName(mdb, beanClass.get());
 
@@ -1554,33 +1503,6 @@ public class AnnotationDeployer implemen
                 LegacyProcessor.process(beanClass.get(), messageBean);
             }
 
-            /*
-            for (Class<?> specializingClass : sortClassesParentFirst(new 
ArrayList<Class<?>>(specializingClasses))) {
-
-                final Class<?> parent = specializingClass.getSuperclass();
-
-                if (parent == null || parent.equals(Object.class)) {
-                    
ejbModule.getValidation().fail(specializingClass.getSimpleName(), 
"specializes.extendsNothing", specializingClass.getName());
-                }
-
-                boolean found = false;
-
-                for (EnterpriseBean enterpriseBean : 
ejbJar.getEnterpriseBeans()) {
-
-                    final String ejbClass = enterpriseBean.getEjbClass();
-
-                    if (ejbClass != null && ejbClass.equals(parent.getName())) 
{
-                        
enterpriseBean.setEjbClass(specializingClass.getName());
-                        found = true;
-                    }
-                }
-
-                if (!found) {
-                    
ejbModule.getValidation().fail(specializingClass.getSimpleName(), 
"specializes.extendsSimpleBean", specializingClass.getName());
-                }
-            }
-            */
-
             AssemblyDescriptor assemblyDescriptor = 
ejbModule.getEjbJar().getAssemblyDescriptor();
             if (assemblyDescriptor == null) {
                 assemblyDescriptor = new AssemblyDescriptor();
@@ -1610,7 +1532,7 @@ public class AnnotationDeployer implemen
                 for (final PersistenceModule pm : 
ejbModule.getAppModule().getPersistenceModules()) {
                     for (final org.apache.openejb.jee.jpa.unit.PersistenceUnit 
pu : pm.getPersistence().getPersistenceUnit()) {
                         if ((pu.isExcludeUnlistedClasses() == null || 
!pu.isExcludeUnlistedClasses())
-                            && 
"true".equalsIgnoreCase(pu.getProperties().getProperty(OPENEJB_JPA_AUTO_SCAN))) 
{
+                                && 
"true".equalsIgnoreCase(pu.getProperties().getProperty(OPENEJB_JPA_AUTO_SCAN))) 
{
                             final String packageName = 
pu.getProperties().getProperty(OPENEJB_JPA_AUTO_SCAN_PACKAGE);
                             String[] packageNames = null;
                             if (packageName != null) {
@@ -1715,30 +1637,24 @@ public class AnnotationDeployer implemen
             //  more classes than actually apply to CDI.  This can "pollute"
             //  the CDI class space and break injection points
 
-            if (!(finder instanceof FinderFactory.ModuleLimitedFinder)) {
-                return finder.getAnnotatedClassNames();
-            }
-
-            final IAnnotationFinder delegate = 
((FinderFactory.ModuleLimitedFinder) finder).getDelegate();
-            if (!(delegate instanceof AnnotationFinder)) {
-                return finder.getAnnotatedClassNames();
-            }
-
-            final AnnotationFinder annotationFinder = (AnnotationFinder) 
delegate;
+            // force cast otherwise we would be broken
+            final IAnnotationFinder delegate = 
FinderFactory.ModuleLimitedFinder.class.isInstance(finder) ?
+                    
FinderFactory.ModuleLimitedFinder.class.cast(finder).getDelegate() : finder;
+            final AnnotationFinder annotationFinder = 
AnnotationFinder.class.cast(delegate);
 
             final Archive archive = annotationFinder.getArchive();
-            if (!(archive instanceof WebappAggregatedArchive)) {
-                return finder.getAnnotatedClassNames();
-            }
+            final List<String> classes = new ArrayList<String>(500);
 
-            final List<String> classes = new ArrayList<String>();
+            if (!WebappAggregatedArchive.class.isInstance(archive)) {
+                return annotationFinder.getAnnotatedClassNames();
+            }
 
             final WebappAggregatedArchive aggregatedArchive = 
(WebappAggregatedArchive) archive;
             final Map<URL, List<String>> map = 
aggregatedArchive.getClassesMap();
 
             for (final Map.Entry<URL, List<String>> entry : map.entrySet()) {
-
-                if (hasBeansXml(entry.getKey())) {
+                final URL beansXml = hasBeansXml(entry.getKey());
+                if (beansXml != null) {
                     classes.addAll(entry.getValue());
                 }
             }
@@ -1746,31 +1662,52 @@ public class AnnotationDeployer implemen
             return classes;
         }
 
-        public static boolean hasBeansXml(final URL url) {
+        public static URL hasBeansXml(final URL url) {
             if (url.getPath().endsWith("WEB-INF/classes/")) {
-                return true;
+                {
+                    final File file = new File(URLs.toFile(url).getParent(), 
"beans.xml");
+                    if (file.exists()) {
+                        try {
+                            return file.toURI().toURL();
+                        } catch (final MalformedURLException e) {
+                            return url;
+                        }
+                    }
+                }
+                {
+                    final File file = new File(URLs.toFile(url), 
"classes/beans.xml");
+                    if (file.exists()) {
+                        try {
+                            return file.toURI().toURL();
+                        } catch (final MalformedURLException e) {
+                            return url;
+                        }
+                    }
+                }
+                return url;
             }
             if (url.getPath().endsWith("!/META-INF/beans.xml")) {
-                return true;
+                return url;
             }
             try {
                 final URLClassLoader loader = new URLClassLoader(new 
URL[]{url}, new EmptyResourcesClassLoader());
                 final String[] paths = {
-                    "META-INF/beans.xml",
-                    "WEB-INF/beans.xml",
-                    "/WEB-INF/beans.xml",
-                    "/META-INF/beans.xml",
+                        "META-INF/beans.xml",
+                        "WEB-INF/beans.xml",
+                        "/WEB-INF/beans.xml",
+                        "/META-INF/beans.xml",
                 };
 
                 for (final String path : paths) {
-                    if (loader.findResource(path) != null) {
-                        return true;
+                    final URL resource = loader.findResource(path);
+                    if (resource != null) {
+                        return resource;
                     }
                 }
             } catch (final Exception e) {
                 // no-op
             }
-            return false;
+            return null;
         }
 
         private String getEjbName(final MessageDriven mdb, final Class<?> 
beanClass) {
@@ -1860,7 +1797,7 @@ public class AnnotationDeployer implemen
              */
             buildAnnotatedRefs(beanInfo, annotationFinder, 
beanInfo.getClassLoader());
 
-            processWebServiceClientHandlers(beanInfo, 
beanInfo.getClassLoader());
+            processWebServiceClientHandlers(beanInfo, annotationFinder, 
beanInfo.getClassLoader());
 
         }
 
@@ -1981,7 +1918,20 @@ public class AnnotationDeployer implemen
 
             validateRemoteClientRefs(classLoader, client, remoteClients);
 
-            processWebServiceClientHandlers(client, classLoader);
+            final IAnnotationFinder finder = clientModule.getFinder();
+            if (!AnnotationFinder.class.isInstance(finder) && finder != null) {
+                final Class<?>[] loadedClasses = new 
Class<?>[finder.getAnnotatedClassNames().size()];
+                int i = 0;
+                for (final String s : finder.getAnnotatedClassNames()) {
+                    try {
+                        loadedClasses[i++] = classLoader.loadClass(s);
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+                clientModule.getFinderReference().set(new 
FinderFactory.OpenEJBAnnotationFinder(new ClassesArchive(loadedClasses)));
+            }
+            processWebServiceClientHandlers(client, 
AnnotationFinder.class.cast(clientModule.getFinder()), classLoader);
 
             return clientModule;
         }
@@ -2096,8 +2046,9 @@ public class AnnotationDeployer implemen
                         try {
                             final Application app = 
Application.class.cast(clazz.newInstance());
                             try {
-                                if (!app.getClasses().isEmpty()) {
-                                    classes.addAll(app.getClasses());
+                                final Set<Class<?>> appClasses = 
app.getClasses();
+                                if (!appClasses.isEmpty()) {
+                                    classes.addAll(appClasses);
                                 } else {
                                     addRestClassesToScannedClasses(webModule, 
classes, classLoader);
                                 }
@@ -2307,7 +2258,7 @@ public class AnnotationDeployer implemen
              */
             buildAnnotatedRefs(webApp, annotationFinder, classLoader);
 
-            processWebServiceClientHandlers(webApp, classLoader);
+            processWebServiceClientHandlers(webApp, annotationFinder, 
classLoader);
 
             return webModule;
         }
@@ -2340,27 +2291,32 @@ public class AnnotationDeployer implemen
                     continue;
                 }
 
-                final boolean dynamicBean = 
DynamicProxyImplFactory.isKnownDynamicallyImplemented(clazz);
                 final MetaAnnotatedClass<?> metaClass = new 
MetaAnnotatedClass(clazz);
+                final boolean dynamicBean = 
DynamicProxyImplFactory.isKnownDynamicallyImplemented(metaClass, clazz);
 
-                final AnnotationFinder finder;
+                AnnotationFinder finder = null; // created lazily since not 
always needed
                 final AnnotationFinder annotationFinder;
-
                 if (ejbModule.getFinder() instanceof AnnotationFinder) {
-                    final AnnotationFinder af = (AnnotationFinder) 
ejbModule.getFinder();
+                    AnnotationFinder af = (AnnotationFinder) 
ejbModule.getFinder();
 
                     final List<Class<?>> ancestors = Classes.ancestors(clazz);
+                    ancestors.addAll(asList(clazz.getInterfaces()));
+                    if (dynamicBean) {
+                        final Proxy p = metaClass.getAnnotation(Proxy.class);
+                        if (p != null) {
+                            ancestors.add(p.value());
+                        }
+                    }
+
                     final String[] names = new String[ancestors.size()];
                     int i = 0;
                     for (final Class<?> ancestor : ancestors) {
                         names[i++] = ancestor.getName();
                     }
                     annotationFinder = af.select(names);
-                    finder = af.select(clazz.getName());
-                } else {
+                } else { // shouldn't occur
                     if (!dynamicBean) {
                         annotationFinder = createFinder(clazz);
-                        finder = new AnnotationFinder(new 
ClassesArchive(clazz));
                     } else {
                         final Class<?>[] classes;
                         final Proxy proxy = 
metaClass.getAnnotation(Proxy.class);
@@ -2370,7 +2326,6 @@ public class AnnotationDeployer implemen
                             classes = new Class<?>[]{clazz, proxy.value()};
                         }
                         annotationFinder = createFinder(classes);
-                        finder = new AnnotationFinder(new 
ClassesArchive(classes));
                     }
                 }
 
@@ -2422,6 +2377,9 @@ public class AnnotationDeployer implemen
                 if (bean.getTransactionType() == TransactionType.CONTAINER) {
                     processAttributes(new 
TransactionAttributeHandler(assemblyDescriptor, ejbName), clazz, 
annotationFinder);
                 } else {
+                    if (finder == null) {
+                        finder = annotationFinder.select(clazz.getName());
+                    }
                     checkAttributes(new 
TransactionAttributeHandler(assemblyDescriptor, ejbName), ejbName, ejbModule, 
finder, "invalidTransactionAttribute");
                 }
 
@@ -2675,7 +2633,7 @@ public class AnnotationDeployer implemen
                              * @AccessTimeout
                              */
                             final AccessTimeoutHandler accessTimeoutHandler =
-                                new AccessTimeoutHandler(assemblyDescriptor, 
sessionBean, lockHandler.getContainerConcurrency());
+                                    new 
AccessTimeoutHandler(assemblyDescriptor, sessionBean, 
lockHandler.getContainerConcurrency());
                             processAttributes(accessTimeoutHandler, clazz, 
annotationFinder);
 
                             /*
@@ -2770,9 +2728,9 @@ public class AnnotationDeployer implemen
                         for (final Class<?> intf : clazz.getInterfaces()) {
                             final String name = intf.getName();
                             if (!name.equals("java.io.Serializable") &&
-                                !name.equals("java.io.Externalizable") &&
-                                !name.startsWith("javax.ejb.") &&
-                                !intf.isSynthetic()) {
+                                    !name.equals("java.io.Externalizable") &&
+                                    !name.startsWith("javax.ejb.") &&
+                                    !intf.isSynthetic()) {
                                 interfaces.add(intf);
                             }
                         }
@@ -2791,9 +2749,9 @@ public class AnnotationDeployer implemen
 
                 buildAnnotatedRefs(bean, annotationFinder, classLoader);
 
-                processWebServiceHandlers(ejbModule, bean);
+                processWebServiceHandlers(ejbModule, bean, annotationFinder);
 
-                processWebServiceClientHandlers(bean, classLoader);
+                processWebServiceClientHandlers(bean, annotationFinder, 
classLoader);
 
                 try {
                     if 
(BeanContext.Comp.class.getName().equals(bean.getEjbClass())) {
@@ -2840,7 +2798,7 @@ public class AnnotationDeployer implemen
                  */
                 buildAnnotatedRefs(interceptor, annotationFinder, classLoader);
 
-                processWebServiceClientHandlers(interceptor, classLoader);
+                processWebServiceClientHandlers(interceptor, annotationFinder, 
classLoader);
 
                 /**
                  * Interceptors do not have their own section in ejb-jar.xml 
for resource references
@@ -3011,15 +2969,15 @@ public class AnnotationDeployer implemen
                     for (final Class<?> interfce : clazz.getInterfaces()) {
                         final String name = interfce.getName();
                         if (!name.equals("scala.ScalaObject") &&
-                            !name.equals("groovy.lang.GroovyObject") &&
-                            !name.equals("java.io.Serializable") &&
-                            !name.equals("java.io.Externalizable") &&
-                            !(name.equals(InvocationHandler.class.getName()) 
&& DynamicSubclass.isDynamic(beanClass)) &&
-                            !name.startsWith("javax.ejb.") &&
-                            !descriptor.contains(interfce.getName()) &&
-                            !interfce.isSynthetic() &&
-                            
!"net.sourceforge.cobertura.coveragedata.HasBeenInstrumented".equals(name) &&
-                            !name.startsWith("org.scalatest.")) {
+                                !name.equals("groovy.lang.GroovyObject") &&
+                                !name.equals("java.io.Serializable") &&
+                                !name.equals("java.io.Externalizable") &&
+                                
!(name.equals(InvocationHandler.class.getName()) && 
DynamicSubclass.isDynamic(beanClass)) &&
+                                !name.startsWith("javax.ejb.") &&
+                                !descriptor.contains(interfce.getName()) &&
+                                !interfce.isSynthetic() &&
+                                
!"net.sourceforge.cobertura.coveragedata.HasBeenInstrumented".equals(name) &&
+                                !name.startsWith("org.scalatest.")) {
                             interfaces.add(interfce);
                         }
                     }
@@ -3231,18 +3189,18 @@ public class AnnotationDeployer implemen
                 // the case of absolutely no metadata at all and attempting to 
figure out the
                 // default view which will be implied as either @LocalBean or 
@Local
                 if (clazz == beanClass
-                    && sessionBean.getLocalBean() == null
-                    && sessionBean.getBusinessLocal().isEmpty()
-                    && sessionBean.getBusinessRemote().isEmpty()
-                    && sessionBean.getHome() == null
-                    && sessionBean.getRemote() == null
-                    && sessionBean.getLocalHome() == null
-                    && sessionBean.getLocal() == null
-                    && all.local.isEmpty()
-                    && all.remote.isEmpty()
-                    ) {
+                        && sessionBean.getLocalBean() == null
+                        && sessionBean.getBusinessLocal().isEmpty()
+                        && sessionBean.getBusinessRemote().isEmpty()
+                        && sessionBean.getHome() == null
+                        && sessionBean.getRemote() == null
+                        && sessionBean.getLocalHome() == null
+                        && sessionBean.getLocal() == null
+                        && all.local.isEmpty()
+                        && all.remote.isEmpty()
+                        ) {
 
-                    if (interfaces.size() == 0 || 
DynamicProxyImplFactory.isKnownDynamicallyImplemented(clazz)) {
+                    if (interfaces.size() == 0 || 
DynamicProxyImplFactory.isKnownDynamicallyImplemented(new 
MetaAnnotatedClass(clazz), clazz)) {
                         // No interfaces?  Then @LocalBean
 
                         sessionBean.setLocalBean(new Empty());
@@ -3261,8 +3219,8 @@ public class AnnotationDeployer implemen
 
                 // do it here to not loose the @Local handling (if 
(interfaces.size() == 1))
                 if (webserviceAsRemote
-                    && webServiceItf != null
-                    && all.remote.isEmpty()) {
+                        && webServiceItf != null
+                        && all.remote.isEmpty()) {
                     all.remote.add(webServiceItf);
                 }
 
@@ -3282,8 +3240,8 @@ public class AnnotationDeployer implemen
         }
 
         private static class BusinessInterfaces {
-            private Set<Class> local = new LinkedHashSet<Class>();
-            private Set<Class> remote = new LinkedHashSet<Class>();
+            private final Set<Class> local = new LinkedHashSet<Class>();
+            private final Set<Class> remote = new LinkedHashSet<Class>();
 
             public void addLocals(final Collection<String> names, final 
ClassLoader loader) {
                 add(loader, names, local);
@@ -3339,8 +3297,8 @@ public class AnnotationDeployer implemen
                      * @RolesAllowed
                      */
                     if ((rolesAllowed != null && permitAll != null)
-                        || (rolesAllowed != null && denyAll != null)
-                        || (permitAll != null && denyAll != null)) {
+                            || (rolesAllowed != null && denyAll != null)
+                            || (permitAll != null && denyAll != null)) {
                         ejbModule.getValidation().fail(ejbName, 
"permitAllAndRolesAllowedOnClass", clazz.getName());
                     }
 
@@ -3373,7 +3331,7 @@ public class AnnotationDeployer implemen
                      */
                     if (denyAll != null) {
                         assemblyDescriptor.getExcludeList()
-                            .addMethod(new 
org.apache.openejb.jee.Method(ejbName, clazz.getName(), "*"));
+                                .addMethod(new 
org.apache.openejb.jee.Method(ejbName, clazz.getName(), "*"));
                     }
                 }
 
@@ -3573,7 +3531,7 @@ public class AnnotationDeployer implemen
                 /*
                  *  @AroundTimeout
                  */
-                if (apply(override, invokable.getAroundInvoke())) {
+                if (apply(override, invokable.getAroundTimeout())) {
                     for (final Annotated<Method> method : 
sortMethods(annotationFinder.findMetaAnnotatedMethods(javax.interceptor.AroundTimeout.class)))
 {
                         invokable.getAroundTimeout().add(new 
AroundTimeout(method.get()));
                     }
@@ -4315,7 +4273,7 @@ public class AnnotationDeployer implemen
                     lookupMissing.add(name);
                     final String exists = getSourceIfExists(cls);
                     logger.warning("Method 'lookup' is not available for '" + 
name + "'"
-                        + (null != exists ? ". The old API '" + exists + "' 
was found on the classpath." : ". Probably using an older Runtime."));
+                            + (null != exists ? ". The old API '" + exists + 
"' was found on the classpath." : ". Probably using an older Runtime."));
                 }
             }
 
@@ -4324,7 +4282,7 @@ public class AnnotationDeployer implemen
 
         private static String getSourceIfExists(final Class<?> cls) {
             if (cls.getProtectionDomain() != null && 
cls.getProtectionDomain().getCodeSource() != null
-                && cls.getProtectionDomain().getCodeSource().getLocation() != 
null) {
+                    && cls.getProtectionDomain().getCodeSource().getLocation() 
!= null) {
                 return 
cls.getProtectionDomain().getCodeSource().getLocation().toString();
             }
             return null;
@@ -4437,21 +4395,21 @@ public class AnnotationDeployer implemen
                 module = ((Module) currentModule.get()).getAppModule();
             }
             if (module != null
-                && 
org.apache.openejb.jee.jpa.unit.TransactionType.RESOURCE_LOCAL.equals(module.getTransactionType(persistenceContext.unitName())))
 {
+                    && 
org.apache.openejb.jee.jpa.unit.TransactionType.RESOURCE_LOCAL.equals(module.getTransactionType(persistenceContext.unitName())))
 {
                 // should it be in warn level?
                 // IMO no since with CDI it is tempting to do so
                 String name = persistenceContext.unitName();
                 if (name == null || name.isEmpty()) { // search for it
                     try { // get the first one
                         name = module.getPersistenceModules().iterator().next()
-                            .getPersistence()
-                            .getPersistenceUnit().iterator().next().getName();
+                                .getPersistence()
+                                
.getPersistenceUnit().iterator().next().getName();
                     } catch (final Exception e) {
                         name = "?";
                     }
                 }
                 logger.info("PersistenceUnit '" + name + "' is a 
RESOURCE_LOCAL one, " +
-                    "you'll have to manage @PersistenceContext yourself.");
+                        "you'll have to manage @PersistenceContext yourself.");
                 return;
             }
 
@@ -4741,9 +4699,9 @@ public class AnnotationDeployer implemen
         /**
          * Scan for @EJB, @Resource, @WebServiceRef, @PersistenceUnit, and 
@PersistenceContext on WebService HandlerChain classes
          */
-        private void processWebServiceHandlers(final EjbModule ejbModule, 
final EnterpriseBean bean) throws OpenEJBException {
+        private void processWebServiceHandlers(final EjbModule ejbModule, 
final EnterpriseBean bean, final AnnotationFinder finder) throws 
OpenEJBException {
             // add webservice handler classes to the class finder used in 
annotation processing
-            final Set<Class<?>> classes = new HashSet<Class<?>>();
+            final Set<String> classes = new HashSet<String>();
             if (ejbModule.getWebservices() != null) {
                 for (final WebserviceDescription webservice : 
ejbModule.getWebservices().getWebserviceDescription()) {
                     for (final PortComponent port : 
webservice.getPortComponent()) {
@@ -4759,19 +4717,15 @@ public class AnnotationDeployer implemen
                             for (final Handler handler : 
handlerChain.getHandler()) {
                                 final String handlerClass = 
realClassName(handler.getHandlerClass());
                                 if (handlerClass != null) {
-                                    try {
-                                        final Class handlerClazz = 
ejbModule.getClassLoader().loadClass(handlerClass);
-                                        classes.add(handlerClazz);
-                                    } catch (final ClassNotFoundException e) {
-                                        throw new OpenEJBException("Unable to 
load webservice handler class: " + handlerClass, e);
-                                    }
+                                    classes.add(handlerClass);
                                 }
                             }
                         }
                     }
                 }
             }
-            final AnnotationFinder handlersFinder = 
createFinder(classes.toArray(new Class<?>[classes.size()]));
+            // classes.add(bean.getEjbClass());
+            final AnnotationFinder handlersFinder = finder.select(classes);
             buildAnnotatedRefs(bean, handlersFinder, 
ejbModule.getClassLoader());
         }
 
@@ -4782,13 +4736,13 @@ public class AnnotationDeployer implemen
          * @param classLoader
          * @throws OpenEJBException
          */
-        private void processWebServiceClientHandlers(final JndiConsumer 
consumer, final ClassLoader classLoader) throws OpenEJBException {
+        private void processWebServiceClientHandlers(final JndiConsumer 
consumer, final AnnotationFinder finder, final ClassLoader classLoader) throws 
OpenEJBException {
             if (SystemInstance.get().hasProperty("openejb.geronimo")) {
                 return;
             }
 
-            final Set<Class<?>> processedClasses = new HashSet<Class<?>>();
-            final Set<Class<?>> handlerClasses = new HashSet<Class<?>>();
+            final Set<String> processedClasses = new HashSet<String>();
+            final Set<String> handlerClasses = new HashSet<String>();
             do {
                 // get unprocessed handler classes
                 handlerClasses.clear();
@@ -4800,20 +4754,19 @@ public class AnnotationDeployer implemen
                     for (final org.apache.openejb.jee.HandlerChain 
handlerChain : chains.getHandlerChain()) {
                         for (final Handler handler : 
handlerChain.getHandler()) {
                             if (handler.getHandlerClass() != null) {
-                                try {
-                                    final Class clazz = 
classLoader.loadClass(realClassName(handler.getHandlerClass()));
-                                    handlerClasses.add(clazz);
-                                } catch (final ClassNotFoundException e) {
-                                    throw new OpenEJBException("Unable to load 
webservice handler class: " + handler.getHandlerClass(), e);
-                                }
+                                
handlerClasses.add(realClassName(handler.getHandlerClass()));
                             }
                         }
                     }
                 }
                 handlerClasses.removeAll(processedClasses);
+                if (handlerClasses.isEmpty()) {
+                    continue;
+                }
 
                 // process handler classes
-                final AnnotationFinder handlerAnnotationFinder = 
createFinder(handlerClasses.toArray(new Class<?>[handlerClasses.size()]));
+                final AnnotationFinder handlerAnnotationFinder = finder != 
null ? finder.select(handlerClasses) :
+                        new FinderFactory.OpenEJBAnnotationFinder(new 
FinderFactory.DoLoadClassesArchive(classLoader, handlerClasses));
 
                 /*
                  * @EJB
@@ -5163,18 +5116,7 @@ public class AnnotationDeployer implemen
             for (final Class<?> clazz : classes) {
                 parents.addAll(Classes.ancestors(clazz));
             }
-
-            return new AnnotationFinder(new ClassesArchive(parents)).link();
-        }
-
-        /**
-         * Copy lists for iteration avoiding ConcurrentModificationException
-         *
-         * @param classes
-         * @return
-         */
-        private List<Class<?>> copy(final List<Class<?>> classes) {
-            return new ArrayList<Class<?>>(classes);
+            return new AnnotationFinder(new 
ClassesArchive(parents)).enableMetaAnnotations(); // no need to have 
subclasses/impl here
         }
 
         /**
@@ -5204,11 +5146,6 @@ public class AnnotationDeployer implemen
             return null;
         }
 
-        private boolean getFirstt(final List<?> list) {
-            return list.size() > 0;
-        }
-
-
         /**
          * Remote interface validation
          *
@@ -5299,9 +5236,9 @@ public class AnnotationDeployer implemen
     }
 
     public static class FilledMember implements Member {
-        private String name;
-        private Class<?> type;
-        private Class<?> declaringClass;
+        private final String name;
+        private final Class<?> type;
+        private final Class<?> declaringClass;
 
         public FilledMember(final String name, final Class<?> type, final 
Class<?> declaringClass) {
             this.name = name;
@@ -5324,10 +5261,10 @@ public class AnnotationDeployer implemen
         @Override
         public String toString() {
             return "FilledMember{" +
-                "name='" + name + '\'' +
-                ", type=" + type.getName() +
-                ", declaringClass=" + declaringClass.getName() +
-                '}';
+                    "name='" + name + '\'' +
+                    ", type=" + type.getName() +
+                    ", declaringClass=" + declaringClass.getName() +
+                    '}';
         }
     }
 
@@ -5469,6 +5406,8 @@ public class AnnotationDeployer implemen
                         webModule.getEjbRestServices().add(name);
                     }
                 }
+            } else if (isEJB(clazz) && DynamicSubclass.isDynamic(clazz)) {
+                classes.add(clazz.getName());
             }
         }
 
@@ -5484,6 +5423,8 @@ public class AnnotationDeployer implemen
                 } else {
                     webModule.getEjbRestServices().add(clazz.getName());
                 }
+            } else if (isEJB(clazz) && DynamicSubclass.isDynamic(clazz)) {
+                classes.add(clazz.getName());
             }
         }
 
@@ -5493,14 +5434,14 @@ public class AnnotationDeployer implemen
     private static boolean isInstantiable(final Class<?> clazz) {
         final int modifiers = clazz.getModifiers();
         return !Modifier.isAbstract(modifiers) && !(clazz.getEnclosingClass() 
!= null && !Modifier.isStatic(modifiers))
-            && Modifier.isPublic(modifiers);
+                && Modifier.isPublic(modifiers);
     }
 
     private static boolean isEJB(final Class<?> clazz) {
         return clazz.isAnnotationPresent(Stateless.class)
-            || clazz.isAnnotationPresent(Singleton.class)
-            || clazz.isAnnotationPresent(ManagedBean.class)  // what a weird 
idea!
-            || clazz.isAnnotationPresent(Stateful.class); // what another 
weird idea!
+                || clazz.isAnnotationPresent(Singleton.class)
+                || clazz.isAnnotationPresent(ManagedBean.class)  // what a 
weird idea!
+                || clazz.isAnnotationPresent(Stateful.class); // what another 
weird idea!
     }
 
     private static String realClassName(final String rawClassName) {

Modified: 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
 Sun Sep  7 13:49:52 2014
@@ -108,6 +108,8 @@ public class DeploymentLoader implements
     private static final Collection<String> KNOWN_DESCRIPTORS = 
Arrays.asList("app-ctx.xml", "module.properties", "application.properties", 
"web.xml", "ejb-jar.xml", "openejb-jar.xml", "env-entries.properties", 
"beans.xml", "ra.xml", "application.xml", "application-client.xml", 
"persistence-fragment.xml", "persistence.xml", "validation.xml", 
NewLoaderLogic.EXCLUSION_FILE);
     private static String ALTDD = 
SystemInstance.get().getOptions().get(OPENEJB_ALTDD_PREFIX, (String) null);
 
+    private volatile List<URL> containerUrls = null;
+
     public AppModule load(final File jarFile) throws OpenEJBException {
         // verify we have a valid file
         final String jarPath;
@@ -918,6 +920,34 @@ public class DeploymentLoader implements
         // determine war class path
 
         final List<URL> webUrls = new ArrayList<URL>();
+        if (containerUrls == null) {
+            if 
("true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.scan.webapp.container",
 "false"))) {
+                synchronized (this) {
+                    if (containerUrls == null) {
+                        try {
+                            UrlSet urlSet = new 
UrlSet(ParentClassLoaderFinder.Helper.get());
+                            urlSet = URLs.cullSystemJars(urlSet);
+                            urlSet = 
NewLoaderLogic.applyBuiltinExcludes(urlSet);
+                            containerUrls = urlSet.getUrls();
+
+                            final Iterator<URL> it = containerUrls.iterator();
+                            while (it.hasNext()) { // remove lib/
+                                final File file = URLs.toFile(it.next());
+                                // TODO: see if websocket should be added in 
default.exclusions
+                                if (file.isDirectory() || 
file.getName().endsWith("tomcat-websocket.jar")) {
+                                    it.remove();
+                                }
+                            }
+                        } catch (final Exception e) {
+                            logger.error(e.getMessage(), e);
+                        }
+                    }
+                }
+            } else {
+                containerUrls = Collections.emptyList();
+            }
+        }
+        webUrls.addAll(containerUrls);
 
         // add these urls first to ensure we load classes from here first
         final String externalRepos = SystemInstance.get().getProperty("tomee." 
+ warFile.getName().replace(".war", "") + ".externalRepositories");
@@ -1121,7 +1151,7 @@ public class DeploymentLoader implements
         try {
             finder = FinderFactory.createFinder(appModule);
         } catch (final Exception e) {
-            finder = new FinderFactory.ModuleLimitedFinder(new 
org.apache.xbean.finder.AnnotationFinder(new 
WebappAggregatedArchive(appModule.getClassLoader(), appModule.getAltDDs(), 
xmls)));
+            finder = new FinderFactory.ModuleLimitedFinder(new 
FinderFactory.OpenEJBAnnotationFinder(new 
WebappAggregatedArchive(appModule.getClassLoader(), appModule.getAltDDs(), 
xmls)));
         }
         appModule.setEarLibFinder(finder);
 

Modified: 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/FinderFactory.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/FinderFactory.java?rev=1623012&r1=1623011&r2=1623012&view=diff
==============================================================================
--- 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/FinderFactory.java
 (original)
+++ 
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/config/FinderFactory.java
 Sun Sep  7 13:49:52 2014
@@ -18,10 +18,17 @@
 package org.apache.openejb.config;
 
 import org.apache.openejb.OpenEJBRuntimeException;
+import org.apache.openejb.jee.Beans;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.Handler;
+import org.apache.openejb.jee.HandlerChain;
+import org.apache.openejb.jee.PortComponent;
+import org.apache.openejb.jee.Servlet;
+import org.apache.openejb.jee.SessionBean;
+import org.apache.openejb.jee.WebserviceDescription;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.xbean.finder.Annotated;
 import org.apache.xbean.finder.AnnotationFinder;
-import org.apache.xbean.finder.AsynchronousInheritanceAnnotationFinder;
 import org.apache.xbean.finder.IAnnotationFinder;
 import org.apache.xbean.finder.UrlSet;
 import org.apache.xbean.finder.archive.Archive;
@@ -38,16 +45,17 @@ import java.lang.reflect.Method;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
+import static org.apache.openejb.util.Classes.ancestors;
+
 public class FinderFactory {
 
     private static final FinderFactory factory = new FinderFactory();
-    public static final String TOMEE_JAXRS_DEPLOY_UNDECLARED_PROP = 
"tomee.jaxrs.deploy.undeclared";
-    public static final String ASYNC_SCAN = 
"openejb.scanning.inheritance.asynchronous";
-    public static final String SKIP_LINK = "openejb.finder.skip.link";
     public static final String FORCE_LINK = "openejb.finder.force.link";
+    private static volatile boolean MODULE_LIMITED = 
"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.finder.module-scoped",
 "false"));
 
     private static FinderFactory get() {
         final FinderFactory factory = 
SystemInstance.get().getComponent(FinderFactory.class);
@@ -63,18 +71,27 @@ public class FinderFactory {
     }
 
     public IAnnotationFinder create(final DeploymentModule module) throws 
Exception {
-        final AnnotationFinder finder;
+        OpenEJBAnnotationFinder finder;
         if (module instanceof WebModule) {
             final WebModule webModule = (WebModule) module;
-            final AnnotationFinder annotationFinder = newFinder(new 
WebappAggregatedArchive(webModule, webModule.getScannableUrls()));
-            enableFinderOptions(annotationFinder);
-            finder = annotationFinder;
+            finder = newFinder(new WebappAggregatedArchive(webModule, 
webModule.getScannableUrls()));
+            if (!finder.foundSomething()) { // test case (AppComposer with new 
WebApp())
+                finder = fallbackAnnotationFinder(module);
+            }
+            finder.link();
         } else if (module instanceof ConnectorModule) {
             final ConnectorModule connectorModule = (ConnectorModule) module;
-            finder = newFinder(new 
ConfigurableClasspathArchive(connectorModule, 
connectorModule.getLibraries())).link();
+            finder = newFinder(new 
ConfigurableClasspathArchive(connectorModule, connectorModule.getLibraries()));
+            if (!finder.foundSomething()) { // test case
+                finder = fallbackAnnotationFinder(module);
+            }
+            finder.link();
         } else if (module instanceof AppModule) {
             final Collection<URL> urls = 
NewLoaderLogic.applyBuiltinExcludes(new 
UrlSet(AppModule.class.cast(module).getAdditionalLibraries())).getUrls();
             finder = newFinder(new 
WebappAggregatedArchive(module.getClassLoader(), module.getAltDDs(), urls));
+            if (!finder.foundSomething()) { // test case
+                finder = fallbackAnnotationFinder(module);
+            }
         } else if (module.getJarLocation() != null) {
             final String location = module.getJarLocation();
             final File file = new File(location);
@@ -97,24 +114,149 @@ public class FinderFactory {
             } else {
                 finder = newFinder(new DebugArchive(new 
ConfigurableClasspathArchive(module.getClassLoader(), url)));
             }
-            if ("true".equals(SystemInstance.get().getProperty(FORCE_LINK, 
module.getProperties().getProperty(FORCE_LINK, "false")))) {
-                finder.link();
-            } else {
-                finder.enableMetaAnnotations(); // needed to stay compliant
-                enableSubclassing(finder);
+            if (!finder.foundSomething()) { // test case too, should be 
removed in absolute. Next else should be hit but if jar location was set we are 
here.
+                finder = fallbackAnnotationFinder(module);
             }
+            finder.link();
         } else {
-            finder = new AnnotationFinder(new ClassesArchive());
+            // TODO: error. Here it means we'll not find anything so helping a 
bit (if you hit it outside a test fix it)
+            finder = fallbackAnnotationFinder(module);
         }
 
-        return new ModuleLimitedFinder(finder);
+        return MODULE_LIMITED ? new ModuleLimitedFinder(finder) : finder;
     }
 
-    private static AnnotationFinder newFinder(final Archive archive) {
-        if ("true".equals(SystemInstance.get().getProperty(ASYNC_SCAN, 
"true"))) {
-            return new AsynchronousInheritanceAnnotationFinder(archive);
+    private OpenEJBAnnotationFinder fallbackAnnotationFinder(DeploymentModule 
module) {
+        final OpenEJBAnnotationFinder finder = new OpenEJBAnnotationFinder(new 
ClassesArchive(ensureMinimalClasses(module)));
+        finder.enableMetaAnnotations();
+        return finder;
+    }
+
+    public static Class<?>[] ensureMinimalClasses(final DeploymentModule 
module) {
+        final Collection<Class<?>> finderClasses = new HashSet<Class<?>>();
+        if (EjbModule.class.isInstance(module)) {
+            final EjbModule ejb = EjbModule.class.cast(module);
+            final EnterpriseBean[] enterpriseBeans = 
ejb.getEjbJar().getEnterpriseBeans();
+
+            ClassLoader classLoader = ejb.getClassLoader();
+            if (classLoader == null) {
+                classLoader = Thread.currentThread().getContextClassLoader();
+            }
+
+            for (final EnterpriseBean bean : enterpriseBeans) {
+                final String name;
+                if (SessionBean.class.isInstance(bean)) {
+                    final SessionBean sessionBean = 
SessionBean.class.cast(bean);
+                    if (sessionBean.getProxy() == null) {
+                        name = sessionBean.getEjbClass();
+                    } else {
+                        name = sessionBean.getProxy();
+                    }
+                } else {
+                    name = bean.getEjbClass();
+                }
+                try {
+                    final Class<?> clazz = classLoader.loadClass(name);
+                    finderClasses.addAll(ancestors(clazz));
+                } catch (final ClassNotFoundException e) {
+                    // no-op
+                }
+            }
+            if (ejb.getWebservices() != null) {
+                for (final WebserviceDescription webservice : 
ejb.getWebservices().getWebserviceDescription()) {
+                    for (final PortComponent port : 
webservice.getPortComponent()) {
+                        if (port.getHandlerChains() == null) {
+                            continue;
+                        }
+                        for (final HandlerChain handlerChain : 
port.getHandlerChains().getHandlerChain()) {
+                            for (final Handler handler : 
handlerChain.getHandler()) {
+                                if (handler.getHandlerClass() != null) {
+                                    try {
+                                        
finderClasses.addAll(ancestors(classLoader.loadClass(handler.getHandlerClass())));
+                                    } catch (final ClassNotFoundException e) {
+                                        // no-op
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            for (final org.apache.openejb.jee.Interceptor interceptor : 
ejb.getEjbJar().getInterceptors()) {
+                try {
+                    
finderClasses.addAll(ancestors(classLoader.loadClass(interceptor.getInterceptorClass())));
+                } catch (final ClassNotFoundException e) {
+                    // no-op
+                }
+            }
+
+            final Beans beans = ejb.getBeans();
+            if (beans != null && ejb.getEjbJar() != null) {
+                for (final String name : beans.getManagedClasses()) {
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(name)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+                for (final String name : beans.getInterceptors()) {
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(name)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+                for (final String name : beans.getAlternativeClasses()) {
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(name)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+                for (final String name : beans.getDecorators()) {
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(name)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+            }
+        } else if (WebModule.class.isInstance(module)) {
+            final WebModule web = WebModule.class.cast(module);
+            final ClassLoader classLoader = web.getClassLoader();
+            if (web.getWebApp() != null) {
+                for (final Servlet s : web.getWebApp().getServlet()) {
+                    final String servletClass = s.getServletClass();
+                    if (servletClass == null) {
+                        continue;
+                    }
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(servletClass)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+                for (final String s : web.getRestClasses()) {
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(s)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+                for (final String s : web.getEjbWebServices()) {
+                    try {
+                        
finderClasses.addAll(ancestors(classLoader.loadClass(s)));
+                    } catch (final ClassNotFoundException e) {
+                        // no-op
+                    }
+                }
+            }
         }
-        return new AnnotationFinder(archive);
+        return finderClasses.toArray(new Class<?>[finderClasses.size()]);
+    }
+
+    private static OpenEJBAnnotationFinder newFinder(final Archive archive) {
+        return new OpenEJBAnnotationFinder(archive);
     }
 
     public static final class DebugArchive implements Archive {
@@ -145,51 +287,10 @@ public class FinderFactory {
         }
     }
 
-    public static AnnotationFinder enableFinderOptions(final AnnotationFinder 
annotationFinder) {
-        if (annotationFinder.hasMetaAnnotations()) {
-            annotationFinder.enableMetaAnnotations();
-        }
-        enableSubclassing(annotationFinder);
-
-        return annotationFinder;
-    }
-
-    private static void enableSubclassing(final AnnotationFinder 
annotationFinder) {
-        if (enableFindSubclasses()) {
-            // for @HandleTypes we need interface impl, impl of abstract 
classes too
-            annotationFinder.enableFindSubclasses();
-            annotationFinder.enableFindImplementations();
-        }
-    }
-
-    private static boolean enableFindSubclasses() {
-        return SystemInstance.get().getOptions().get(FORCE_LINK, false)
-            || !SystemInstance.get().getOptions().get(SKIP_LINK, false)
-            && (isTomEE() || isJaxRsInstalled() && 
SystemInstance.get().getOptions().get(TOMEE_JAXRS_DEPLOY_UNDECLARED_PROP, 
false));
-    }
-
-    public static boolean isTomEE() {
-        try { // since Tomcat 7.0.47
-            
FinderFactory.class.getClassLoader().loadClass("javax.websocket.Endpoint");
-            return true;
-        } catch (final Throwable e) {
-            return false;
-        }
-    }
-
-    public static boolean isJaxRsInstalled() {
-        try {
-            
FinderFactory.class.getClassLoader().loadClass("org.apache.openejb.server.rest.RsRegistry");
-            return true;
-        } catch (final Throwable e) {
-            return false;
-        }
-    }
-
     public static class ModuleLimitedFinder implements IAnnotationFinder {
-        private final IAnnotationFinder delegate;
+        private final OpenEJBAnnotationFinder delegate;
 
-        public ModuleLimitedFinder(final IAnnotationFinder delegate) {
+        public ModuleLimitedFinder(final OpenEJBAnnotationFinder delegate) {
             this.delegate = delegate;
         }
 
@@ -211,7 +312,7 @@ public class FinderFactory {
         @Override
         public List<Class<?>> findAnnotatedClasses(final Class<? extends 
Annotation> annotation) {
             try {
-                return filter(delegate.findAnnotatedClasses(annotation), new 
ClassPredicate<Object>(getAnnotatedClassNames()));
+                return filter(delegate.findAnnotatedClasses(annotation), new 
ClassPredicate(getAnnotatedClassNames()));
             } catch (final TypeNotPresentException tnpe) {
                 throw handleException(tnpe, annotation);
             }
@@ -243,7 +344,7 @@ public class FinderFactory {
 
         @Override
         public List<Class<?>> findInheritedAnnotatedClasses(final Class<? 
extends Annotation> annotation) {
-            return filter(delegate.findInheritedAnnotatedClasses(annotation), 
new ClassPredicate<Object>(getAnnotatedClassNames()));
+            return filter(delegate.findInheritedAnnotatedClasses(annotation), 
new ClassPredicate(getAnnotatedClassNames()));
         }
 
         @Override
@@ -263,7 +364,7 @@ public class FinderFactory {
 
         @Override
         public List<Class<?>> findClassesInPackage(final String packageName, 
final boolean recursive) {
-            return filter(delegate.findClassesInPackage(packageName, 
recursive), new ClassPredicate<Object>(getAnnotatedClassNames()));
+            return filter(delegate.findClassesInPackage(packageName, 
recursive), new ClassPredicate(getAnnotatedClassNames()));
         }
 
         @Override
@@ -405,4 +506,50 @@ public class FinderFactory {
             }
         }
     }
+
+    public static class OpenEJBAnnotationFinder extends AnnotationFinder {
+        private static final String[] JVM_SCANNING_CONFIG = 
SystemInstance.get().getProperty("openejb.scanning.xbean.jvm", 
"java.").split(",");
+
+        public OpenEJBAnnotationFinder(final Archive archive) {
+            super(archive);
+        }
+
+        @Override
+        protected boolean isJvm(final String name) {
+            return sharedIsJvm(name);
+        }
+
+        // don't reuse URLClassLoaderFirst one since this one can kill 
scanning perf
+        // using a raw but efficient impl
+        public static boolean sharedIsJvm(final String name) {
+            for (final String s : JVM_SCANNING_CONFIG) {
+                if (name.startsWith(s)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public boolean foundSomething() {
+            return !classInfos.isEmpty();
+        }
+    }
+
+    public static class DoLoadClassesArchive extends ClassesArchive {
+        public DoLoadClassesArchive(final ClassLoader loader, final 
Collection<String> classes) {
+            super(load(loader, classes));
+        }
+
+        private static Iterable<Class<?>> load(final ClassLoader loader, final 
Collection<String> classes) {
+            final Collection<Class<?>> loaded = new 
ArrayList<Class<?>>(classes.size());
+            for (final String n : classes) {
+                try {
+                    loaded.add(loader.loadClass(n));
+                } catch (final ClassNotFoundException e) {
+                    // no-op
+                }
+            }
+            return loaded;
+        }
+    }
 }


Reply via email to