You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2012/04/25 15:09:40 UTC

svn commit: r1330257 - in /openejb/trunk/openejb: container/openejb-core/src/main/java/org/apache/openejb/config/ container/openejb-core/src/main/resources/META-INF/ tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ tomee/tomee-embedded/src...

Author: dblevins
Date: Wed Apr 25 13:09:40 2012
New Revision: 1330257

URL: http://svn.apache.org/viewvc?rev=1330257&view=rev
Log:
TOMEE-169 - cache and share results of scanning tld files
TOMEE-164 - use default.excludes when scanning for tld files
TOMEE-168 - Load OpenEJB System applications directly, without scanning
TOMEE-167 - Disable support for legacy v2 openejb-jar.xml by default. Only needed for Geronimo
TOMEE-166 - Web.xml metadata-complete effectively ignored

Added:
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java
    openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Warmup.java
Removed:
    openejb/trunk/openejb/container/openejb-core/src/main/resources/META-INF/application-client.xml
Modified:
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
    openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatLoader.java
    openejb/trunk/openejb/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java
    openejb/trunk/openejb/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java?rev=1330257&r1=1330256&r2=1330257&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java Wed Apr 25 13:09:40 2012
@@ -447,13 +447,23 @@ public class ConfigurationFactory implem
         }
 
         final boolean embedded = SystemInstance.get().hasProperty(EJBContainer.class.getName());
-        if (SystemInstance.get().getOptions().get(DEPLOYMENTS_CLASSPATH_PROPERTY, !embedded)) {
+        final Options options = SystemInstance.get().getOptions();
+
+        if (options.get("openejb.system.apps", false)) {
+            try {
+                final AppInfo appInfo = configureApplication(new AppModule(SystemApps.getSystemModule()));
+                sys.containerSystem.applications.add(appInfo);
+            } catch (OpenEJBException e) {
+                logger.error("Unable to load the system applications.", e);
+            }
+        } else if (options.get(DEPLOYMENTS_CLASSPATH_PROPERTY, !embedded)) {
+
             final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 
             final ArrayList<File> jarFiles = getModulesFromClassPath(declaredApps, classLoader);
             final String appId = "classpath.ear";
 
-            final boolean classpathAsEar = SystemInstance.get().getOptions().get(CLASSPATH_AS_EAR, true);
+            final boolean classpathAsEar = options.get(CLASSPATH_AS_EAR, true);
             try {
                 if (classpathAsEar && !jarFiles.isEmpty()) {
 

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java?rev=1330257&r1=1330256&r2=1330257&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java Wed Apr 25 13:09:40 2012
@@ -51,6 +51,7 @@ import org.apache.xbean.finder.IAnnotati
 import org.apache.xbean.finder.ResourceFinder;
 import org.apache.xbean.finder.UrlSet;
 import org.apache.xbean.finder.archive.Archive;
+import org.apache.xbean.finder.archive.ClassesArchive;
 import org.apache.xbean.finder.archive.JarArchive;
 import org.xml.sax.SAXException;
 
@@ -71,7 +72,6 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -83,6 +83,8 @@ import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
 import static org.apache.openejb.config.NewLoaderLogic.applyBuiltinExcludes;
+import static org.apache.openejb.config.TldScanner.scanForTagLibs;
+import static org.apache.openejb.config.TldScanner.scanWarForTagLibs;
 import static org.apache.openejb.util.URLs.toFile;
 
 /**
@@ -678,9 +680,17 @@ public class DeploymentLoader implements
 
         try {
             // TODO:  Put our scanning ehnancements back, here
-            final IAnnotationFinder finder = FinderFactory.createFinder(webModule);
-            webModule.setFinder(finder);
-            webEjbModule.setFinder(finder);
+            fillEjbJar(webModule, webEjbModule);
+
+            if (isMetadataComplete(webModule, webEjbModule)) {
+                final IAnnotationFinder finder = new org.apache.xbean.finder.AnnotationFinder(new ClassesArchive());
+                webModule.setFinder(finder);
+                webEjbModule.setFinder(finder);
+            }  else {
+                final IAnnotationFinder finder = FinderFactory.createFinder(webModule);
+                webModule.setFinder(finder);
+                webEjbModule.setFinder(finder);
+            }
         } catch (Exception e) {
             throw new OpenEJBException("Unable to create annotation scanner for web module " + webModule.getModuleId(), e);
         }
@@ -688,6 +698,40 @@ public class DeploymentLoader implements
         addWebservices(webEjbModule);
     }
 
+    /**
+     * If the web.xml is metadata-complete and there is no ejb-jar.xml
+     * then per specification we use the web.xml metadata-complete setting
+     * to imply the same for EJBs.
+     *
+     * @param webModule
+     * @param ejbModule
+     */
+    private void fillEjbJar(WebModule webModule, EjbModule ejbModule) {
+        final Object o = webModule.getAltDDs().get("ejb-jar.xml");
+        if (o != null) return;
+        if (ejbModule.getEjbJar() != null) return;
+
+        final EjbJar ejbJar = new EjbJar();
+        final WebApp webApp = webModule.getWebApp();
+
+        ejbJar.setMetadataComplete(webApp.isMetadataComplete());
+
+        ejbModule.setEjbJar(ejbJar);
+    }
+
+    private boolean isMetadataComplete(WebModule webModule, EjbModule ejbModule) {
+        if (webModule.getWebApp() == null) return false;
+        if (!webModule.getWebApp().isMetadataComplete()) return false;
+
+        // At this point we know the web.xml is metadata-complete
+        // We need to determine if there are cdi or ejb xml files
+        if (webModule.getAltDDs().get("beans.xml") == null) return true;
+        if (ejbModule.getEjbJar() == null) return true;
+        if (!ejbModule.getEjbJar().isMetadataComplete()) return false;
+
+        return true;
+    }
+
     public WebModule createWebModule(final String appId, final String warPath, final ClassLoader parentClassLoader, final String contextRoot, final String moduleName) throws OpenEJBException {
         File warFile = new File(warPath);
         if (!warFile.isDirectory()) {
@@ -959,7 +1003,7 @@ public class DeploymentLoader implements
 
         // Search all libs
         final ClassLoader parentClassLoader = webModule.getClassLoader().getParent();
-        urls = scanClassLoaderForTagLibs(parentClassLoader);
+        urls = TldScanner.scan(parentClassLoader);
         tldLocations.addAll(urls);
 
         // load the tld files
@@ -1044,144 +1088,6 @@ public class DeploymentLoader implements
         }
     }
 
-    private static Set<URL> scanClassLoaderForTagLibs(final ClassLoader parentClassLoader) throws OpenEJBException {
-        final Set<URL> urls = new HashSet<URL>();
-        if (parentClassLoader == null) return urls;
-
-        UrlSet urlSet;
-        try {
-            urlSet = new UrlSet(parentClassLoader);
-            urlSet = URLs.cullSystemJars(urlSet);
-        } catch (IOException e) {
-            logger.warning("Error scanning class loader for JSP tag libraries", e);
-            return urls;
-        }
-
-        for (URL url : urlSet.getUrls()) {
-            if (url.getProtocol().equals("jar")) {
-                try {
-                    String path = url.getPath();
-                    if (path.endsWith("!/")) {
-                        path = path.substring(0, path.length() - 2);
-                    }
-                    url = new URL(path);
-                } catch (MalformedURLException e) {
-                    logger.warning("JSP tag library location bad: " + url.toExternalForm(), e);
-                    continue;
-                }
-            }
-
-            if (!url.getProtocol().equals("file")) {
-                continue;
-            }
-
-            File file = toFile(url);
-            try {
-                file = file.getCanonicalFile().getAbsoluteFile();
-            } catch (IOException e) {
-                logger.warning("JSP tag library location bad: " + file.getAbsolutePath(), e);
-                continue;
-            }
-
-            urls.addAll(scanForTagLibs(file));
-        }
-        return urls;
-    }
-
-    private static Set<URL> scanWarForTagLibs(final File war) {
-        final Set<URL> urls = new HashSet<URL>();
-
-        final File webInfDir = new File(war, "WEB-INF");
-        if (!webInfDir.isDirectory()) return urls;
-
-
-        // skip the lib and classes dir in WEB-INF
-        final LinkedList<File> files = new LinkedList<File>();
-        final File[] list = webInfDir.listFiles();
-        if (list != null) {
-            for (final File file : list) {
-                if ("lib".equals(file.getName()) || "classes".equals(file.getName())) {
-                    continue;
-                }
-                files.add(file);
-            }
-        }
-
-        if (files.isEmpty()) return urls;
-
-        // recursively scan the directories
-        while (!files.isEmpty()) {
-            File file = files.removeFirst();
-            if (file.isDirectory()) {
-                final File[] a = file.listFiles();
-                if (a != null) {
-                    files.addAll(Arrays.asList(a));
-                }
-            } else if (file.getName().endsWith(".tld")) {
-                try {
-                    file = file.getCanonicalFile().getAbsoluteFile();
-                    urls.add(file.toURI().toURL());
-                } catch (IOException e) {
-                    logger.warning("JSP tag library location bad: " + file.getAbsolutePath(), e);
-                }
-            }
-        }
-
-        return urls;
-    }
-
-    private static Set<URL> scanForTagLibs(final File file) {
-        final Set<URL> tldLocations = new HashSet<URL>();
-        try {
-            final String location = file.toURI().toURL().toExternalForm();
-
-            if (location.endsWith(".jar")) {
-                final Set<URL> urls = scanJarForTagLibs(file);
-                tldLocations.addAll(urls);
-            } else if (file.getName().endsWith(".tld")) {
-                final URL url = file.toURI().toURL();
-                tldLocations.add(url);
-            }
-        } catch (IOException e) {
-            logger.warning("Error scanning for JSP tag libraries: " + file.getAbsolutePath(), e);
-        }
-
-        return tldLocations;
-    }
-
-    private static Set<URL> scanJarForTagLibs(final File file) {
-        final Set<URL> urls = new HashSet<URL>();
-
-        if (!file.isFile()) return urls;
-
-        JarFile jarFile = null;
-        try {
-            jarFile = new JarFile(file);
-
-            final URL jarFileUrl = new URL("jar", "", -1, file.toURI().toURL().toExternalForm() + "!/");
-            for (final JarEntry entry : Collections.list(jarFile.entries())) {
-                final String name = entry.getName();
-                if (!name.startsWith("META-INF/") || !name.endsWith(".tld")) {
-                    continue;
-                }
-                final URL url = new URL(jarFileUrl, name);
-                urls.add(url);
-            }
-        } catch (IOException e) {
-            logger.warning("Error scanning jar for JSP tag libraries: " + file.getAbsolutePath(), e);
-        } finally {
-            if (jarFile != null) {
-                try {
-                    jarFile.close();
-                } catch (IOException e) {
-                    // exception ignored
-                }
-            }
-        }
-
-        return urls;
-    }
-
     protected static ConnectorModule createConnectorModule(final String appId, final String rarPath, final ClassLoader parentClassLoader, final String moduleId) throws OpenEJBException {
         final URL baseUrl;// unpack the rar file
         File rarFile = new File(rarPath);

Added: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java?rev=1330257&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java Wed Apr 25 13:09:40 2012
@@ -0,0 +1,67 @@
+/*
+ * 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.config;
+
+import org.apache.openejb.assembler.DeployerEjb;
+import org.apache.openejb.assembler.classic.cmd.ConfigurationInfoEjb;
+import org.apache.openejb.assembler.monitoring.JMXDeployer;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.jee.oejb3.EjbDeployment;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.mgmt.MEJBBean;
+
+/**
+ * Avoids the needs to scan the classpath to load system applications that are used
+ * for deploy tools and other command line tooling.
+ */
+public class SystemApps {
+
+    public static EjbModule getSystemModule() {
+        final EjbModule module = new EjbModule(new EjbJar("openejb"), new OpenejbJar());
+
+        final OpenejbJar openejbJar = module.getOpenejbJar();
+        final EjbJar ejbJar = module.getEjbJar();
+
+        ejbJar.addEnterpriseBean(new StatelessBean(null, DeployerEjb.class));
+        ejbJar.addEnterpriseBean(new StatelessBean(null, ConfigurationInfoEjb.class));
+        ejbJar.addEnterpriseBean(new StatelessBean(null, MEJBBean.class));
+        module.getMbeans().add(JMXDeployer.class.getName());
+
+        final String className = "org.apache.tomee.catalina.deployer.WebappDeployer";
+        if (exists(className)) {
+            final StatelessBean bean = ejbJar.addEnterpriseBean(new StatelessBean("openejb/WebappDeployer", className));
+            final EjbDeployment deployment = openejbJar.addEjbDeployment(bean);
+            deployment.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.annotationName}");
+        }
+
+
+        openejbJar.getProperties().put("openejb.deploymentId.format", "{ejbName}");
+        openejbJar.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.openejbLegacyName}");
+
+        return module;
+    }
+
+    private static boolean exists(String className) {
+        try {
+            SystemApps.class.getClassLoader().loadClass(className);
+            return true;
+        } catch (Throwable t) {
+            return false;
+        }
+    }
+}

Added: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java?rev=1330257&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java Wed Apr 25 13:09:40 2012
@@ -0,0 +1,230 @@
+/*
+ * 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.config;
+
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.util.URLs;
+import org.apache.xbean.finder.UrlSet;
+import org.apache.xbean.finder.filter.Filters;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import static org.apache.openejb.config.NewLoaderLogic.applyBuiltinExcludes;
+import static org.apache.openejb.util.URLs.toFile;
+
+/**
+ * TLD file urls cached on a per classloader basis.  Helps with sharing TLD
+ * files between webapps by placing them in a parent classloader.
+ *
+ * Each webapp will be able to retrieve the cached version of the URLs and
+ * therefore only needs to scan its own libraries, the parent libraries will
+ * already have been scanned.
+ *
+ * For a tiny bit of performance, we will scan the StandardClassloader at boot
+ * in a separate thread so it should be primed in advance of any deployment.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TldScanner {
+
+    private static Map<ClassLoader, Set<URL>> cache = new WeakHashMap<ClassLoader, Set<URL>>();
+
+    public static Set<URL> scan(final ClassLoader classLoader) throws OpenEJBException {
+        if (classLoader == null) return Collections.EMPTY_SET;
+
+        final Set<URL> urls = cache.get(classLoader);
+        if (urls != null) return urls;
+
+        final Set<URL> result = scanClassLoaderForTagLibs(classLoader);
+        cache.put(classLoader, result);
+
+        return result;
+    }
+
+    public static Set<URL> scanClassLoaderForTagLibs(final ClassLoader classLoader) throws OpenEJBException {
+
+        final Set<URL> tldUrls = new HashSet<URL>();
+
+        if (classLoader == null) return tldUrls;
+        if (classLoader == Object.class.getClassLoader()) return tldUrls;
+
+        tldUrls.addAll(scan(classLoader.getParent()));
+
+
+        UrlSet urlSet = new UrlSet();
+
+        if (classLoader instanceof URLClassLoader) {
+
+            final URLClassLoader urlClassLoader = (URLClassLoader) classLoader;
+            urlSet = new UrlSet(urlClassLoader.getURLs());
+
+        } else {
+            try {
+                urlSet = new UrlSet(classLoader);
+            } catch (IOException e) {
+                DeploymentLoader.logger.warning("Error scanning class loader for JSP tag libraries", e);
+            }
+        }
+
+        try {
+            urlSet = URLs.cullSystemJars(urlSet);
+            urlSet = applyBuiltinExcludes(urlSet, Filters.tokens("jstl-1.2", "myfaces-impl"));
+        } catch (IOException e) {
+            DeploymentLoader.logger.warning("Error scanning class loader for JSP tag libraries", e);
+        }
+
+
+        for (URL url : urlSet.getUrls()) {
+            if (url.getProtocol().equals("jar")) {
+                try {
+                    String path = url.getPath();
+                    if (path.endsWith("!/")) {
+                        path = path.substring(0, path.length() - 2);
+                    }
+                    url = new URL(path);
+                } catch (MalformedURLException e) {
+                    DeploymentLoader.logger.warning("JSP tag library location bad: " + url.toExternalForm(), e);
+                    continue;
+                }
+            }
+
+            if (!url.getProtocol().equals("file")) {
+                continue;
+            }
+
+            File file = toFile(url);
+            try {
+                file = file.getCanonicalFile().getAbsoluteFile();
+            } catch (IOException e) {
+                DeploymentLoader.logger.warning("JSP tag library location bad: " + file.getAbsolutePath(), e);
+                continue;
+            }
+
+            tldUrls.addAll(scanForTagLibs(file));
+        }
+
+        return tldUrls;
+    }
+
+    static Set<URL> scanWarForTagLibs(final File war) {
+        final Set<URL> urls = new HashSet<URL>();
+
+        final File webInfDir = new File(war, "WEB-INF");
+        if (!webInfDir.isDirectory()) return urls;
+
+
+        // skip the lib and classes dir in WEB-INF
+        final LinkedList<File> files = new LinkedList<File>();
+        final File[] list = webInfDir.listFiles();
+        if (list != null) {
+            for (final File file : list) {
+                if ("lib".equals(file.getName()) || "classes".equals(file.getName())) {
+                    continue;
+                }
+                files.add(file);
+            }
+        }
+
+        if (files.isEmpty()) return urls;
+
+        // recursively scan the directories
+        while (!files.isEmpty()) {
+            File file = files.removeFirst();
+            if (file.isDirectory()) {
+                final File[] a = file.listFiles();
+                if (a != null) {
+                    files.addAll(Arrays.asList(a));
+                }
+            } else if (file.getName().endsWith(".tld")) {
+                try {
+                    file = file.getCanonicalFile().getAbsoluteFile();
+                    urls.add(file.toURI().toURL());
+                } catch (IOException e) {
+                    DeploymentLoader.logger.warning("JSP tag library location bad: " + file.getAbsolutePath(), e);
+                }
+            }
+        }
+
+        return urls;
+    }
+
+    static Set<URL> scanForTagLibs(final File file) {
+        final Set<URL> tldLocations = new HashSet<URL>();
+        try {
+            final String location = file.toURI().toURL().toExternalForm();
+
+            if (location.endsWith(".jar")) {
+                final Set<URL> urls = scanJarForTagLibs(file);
+                tldLocations.addAll(urls);
+            } else if (file.getName().endsWith(".tld")) {
+                final URL url = file.toURI().toURL();
+                tldLocations.add(url);
+            }
+        } catch (IOException e) {
+            DeploymentLoader.logger.warning("Error scanning for JSP tag libraries: " + file.getAbsolutePath(), e);
+        }
+
+        return tldLocations;
+    }
+
+    static Set<URL> scanJarForTagLibs(final File file) {
+        final Set<URL> urls = new HashSet<URL>();
+
+        if (!file.isFile()) return urls;
+
+        JarFile jarFile = null;
+        try {
+            jarFile = new JarFile(file);
+
+            final URL jarFileUrl = new URL("jar", "", -1, file.toURI().toURL().toExternalForm() + "!/");
+            for (final JarEntry entry : Collections.list(jarFile.entries())) {
+                final String name = entry.getName();
+                if (!name.startsWith("META-INF/") || !name.endsWith(".tld")) {
+                    continue;
+                }
+                final URL url = new URL(jarFileUrl, name);
+                urls.add(url);
+            }
+        } catch (IOException e) {
+            DeploymentLoader.logger.warning("Error scanning jar for JSP tag libraries: " + file.getAbsolutePath(), e);
+        } finally {
+            if (jarFile != null) {
+                try {
+                    jarFile.close();
+                } catch (IOException e) {
+                    // exception ignored
+                }
+            }
+        }
+
+        return urls;
+    }
+}

Modified: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatLoader.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatLoader.java?rev=1330257&r1=1330256&r2=1330257&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatLoader.java (original)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatLoader.java Wed Apr 25 13:09:40 2012
@@ -87,6 +87,10 @@ import java.util.Set;
  */
 public class TomcatLoader implements Loader {
 
+    static {
+        Warmup.warmup();
+    }
+
     private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, TomcatLoader.class);
     public static final String TOMEE_NOSHUTDOWNHOOK_PROP = "tomee.noshutdownhook";
 
@@ -124,8 +128,10 @@ public class TomcatLoader implements Loa
     }
 
     public void initDefaults(Properties properties) {
-        setIfNull(properties, "openejb.deployments.classpath", "true");
+        setIfNull(properties, "openejb.system.apps", "true");
+        setIfNull(properties, "openejb.deployments.classpath", "false");
         setIfNull(properties, "openejb.deployments.classpath.filter.systemapps", "false");
+        setIfNull(properties, "openejb.vendor.config", "glassfish");
 
         //Sets default service provider
         setIfNull(properties, "openejb.provider.default", "org.apache.tomee");

Added: openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Warmup.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Warmup.java?rev=1330257&view=auto
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Warmup.java (added)
+++ openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/Warmup.java Wed Apr 25 13:09:40 2012
@@ -0,0 +1,211 @@
+/*
+ * 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.tomee.catalina;
+
+import org.apache.openejb.config.TldScanner;
+import org.apache.openejb.jee.JaxbJavaee;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.util.DaemonThreadFactory;
+
+import javax.xml.bind.JAXBException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * The classes listed and loaded eagerly have static initializers which take a tiny bit of time.
+ * These initializers cannot be actually run in parallel because classes are loaded serially,
+ * but executing them back to back does help speed things up a bit.
+ *
+ * @version $Rev$ $Date$
+ */
+public class Warmup {
+
+    /**
+     * Referencing this method is enough to cause the static initializer
+     * to be called.  Referencing this method in several classes is therefore safe.
+     *
+     * This method itself does nothing.
+     */
+    public static void warmup() {
+    }
+
+    static {
+        initialize();
+    }
+
+    private static void initialize() {
+        final String[] classes = {
+                "java.util.concurrent.TimeUnit",
+                "java.util.concurrent.atomic.AtomicLong",
+                "javassist.util.proxy.ProxyFactory",
+                "javax.el.ExpressionFactory",
+                "javax.faces.component.UIViewRoot",
+                "javax.imageio.ImageIO",
+                "javax.naming.spi.NamingManager",
+                "javax.servlet.ServletOutputStream",
+                "org.apache.bval.jsr303.ApacheValidatorFactory",
+                "org.apache.bval.jsr303.ConstraintAnnotationAttributes",
+                "org.apache.bval.jsr303.ConstraintDefaults",
+                "org.apache.bval.jsr303.groups.GroupsComputer",
+                "org.apache.bval.jsr303.xml.ValidationMappingParser",
+                "org.apache.bval.util.PrivilegedActions",
+                "org.apache.catalina.authenticator.AuthenticatorBase",
+                "org.apache.catalina.connector.Connector",
+                "org.apache.catalina.connector.CoyoteAdapter",
+                "org.apache.catalina.connector.Request",
+                "org.apache.catalina.connector.Response",
+                "org.apache.catalina.core.ApplicationFilterChain",
+                "org.apache.catalina.core.StandardContext",
+                "org.apache.catalina.core.StandardServer",
+                "org.apache.catalina.deploy.NamingResources",
+                "org.apache.catalina.loader.WebappLoader",
+                "org.apache.catalina.mbeans.GlobalResourcesLifecycleListener",
+                "org.apache.catalina.mbeans.MBeanUtils",
+                "org.apache.catalina.realm.RealmBase",
+                "org.apache.catalina.security.SecurityUtil",
+                "org.apache.catalina.servlets.DefaultServlet",
+                "org.apache.catalina.session.ManagerBase",
+                "org.apache.catalina.startup.Bootstrap",
+                "org.apache.catalina.startup.Catalina",
+                "org.apache.catalina.startup.CatalinaProperties",
+                "org.apache.catalina.startup.ContextConfig",
+                "org.apache.catalina.users.MemoryUserDatabase",
+                "org.apache.catalina.util.ExtensionValidator",
+                "org.apache.catalina.util.LifecycleBase",
+                "org.apache.catalina.util.ServerInfo",
+                "org.apache.catalina.valves.AccessLogValve",
+                "org.apache.catalina.valves.ValveBase",
+                "org.apache.coyote.AbstractProtocol",
+                "org.apache.coyote.ajp.AbstractAjpProtocol",
+                "org.apache.coyote.http11.AbstractHttp11Protocol",
+                "org.apache.geronimo.transaction.manager.TransactionManagerImpl",
+                "org.apache.jasper.compiler.JspRuntimeContext",
+                "org.apache.juli.logging.DirectJDKLog",
+                "org.apache.myfaces.context.servlet.ServletExternalContextImplBase",
+                "org.apache.myfaces.shared.config.MyfacesConfig",
+                "org.apache.myfaces.spi.WebConfigProviderFactory",
+                "org.apache.naming.ContextBindings",
+                "org.apache.naming.resources.BaseDirContext",
+                "org.apache.openejb.ClassLoaderUtil",
+                "org.apache.openejb.InterfaceType",
+                "org.apache.openejb.assembler.classic.Assembler",
+                "org.apache.openejb.assembler.classic.AssemblerTool",
+                "org.apache.openejb.cdi.CdiBuilder",
+                "org.apache.openejb.cdi.ThreadSingletonServiceImpl",
+                "org.apache.openejb.config.AnnotationDeployer",
+                "org.apache.openejb.config.AnnotationDeployer$4",
+                "org.apache.openejb.config.AppValidator",
+                "org.apache.openejb.config.AutoConfig",
+                "org.apache.openejb.config.ConfigurationFactory",
+                "org.apache.openejb.config.MBeanDeployer",
+                "org.apache.openejb.config.NewLoaderLogic",
+                "org.apache.openejb.config.PersistenceContextAnnFactory",
+                "org.apache.openejb.config.sys.JaxbJavaee",
+                "org.apache.openejb.core.ServerFederation",
+                "org.apache.openejb.core.ivm.EjbHomeProxyHandler$1",
+                "org.apache.openejb.core.ivm.EjbHomeProxyHandler$MethodType",
+                "org.apache.openejb.core.managed.ManagedContainer$MethodType",
+                "org.apache.openejb.loader.FileUtils",
+                "org.apache.openejb.loader.IO",
+                "org.apache.openejb.loader.SystemInstance",
+                "org.apache.openejb.monitoring.StatsInterceptor",
+                "org.apache.openejb.persistence.JtaEntityManagerRegistry",
+                "org.apache.openejb.server.ServiceLogger",
+                "org.apache.openejb.server.ejbd.EjbDaemon",
+                "org.apache.openejb.server.ejbd.EjbRequestHandler",
+                "org.apache.openejb.util.Duration",
+                "org.apache.openejb.util.Join",
+                "org.apache.openejb.util.JuliLogStreamFactory",
+                "org.apache.openejb.util.LogCategory",
+                "org.apache.openejb.util.Logger",
+                "org.apache.openejb.util.Messages",
+                "org.apache.openejb.util.SafeToolkit",
+                "org.apache.openejb.util.StringTemplate",
+                "org.apache.openejb.util.proxy.ProxyManager",
+                "org.apache.openjpa.enhance.PCRegistry",
+                "org.apache.openjpa.lib.util.Localizer",
+                "org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap",
+                "org.apache.tomcat.util.buf.B2CConverter",
+                "org.apache.tomcat.util.buf.ByteChunk",
+                "org.apache.tomcat.util.digester.Digester",
+                "org.apache.tomcat.util.file.Matcher",
+                "org.apache.tomcat.util.http.Cookies",
+                "org.apache.tomcat.util.http.HttpMessages",
+                "org.apache.tomcat.util.http.mapper.Mapper",
+                "org.apache.tomcat.util.net.AbstractEndpoint",
+                "org.apache.tomcat.util.scan.StandardJarScanner",
+                "org.apache.tomcat.util.threads.ThreadPoolExecutor",
+                "org.apache.tomee.catalina.BackportUtil",
+                "org.apache.tomee.catalina.BackportUtil$1",
+                "org.apache.tomee.catalina.TomcatLoader",
+                "org.apache.webbeans.config.WebBeansFinder",
+                "org.apache.webbeans.container.InjectionResolver",
+                "org.apache.webbeans.util.WebBeansUtil",
+                "org.apache.webbeans.web.context.WebContextsService",
+                "org.apache.xbean.naming.reference.SimpleReference",
+                "org.apache.xbean.propertyeditor.PropertyEditors",
+                "org.apache.xbean.propertyeditor.ReferenceIdentityMap",
+                "org.apache.xbean.recipe.ReflectionUtil",
+                "org.slf4j.LoggerFactory",
+                "org.slf4j.impl.StaticLoggerBinder",
+        };
+
+        final ExecutorService executor = Executors.newFixedThreadPool(4, new DaemonThreadFactory("warmup"));
+
+        executor.execute(new JaxbJavaeeLoad(WebApp.class));
+        executor.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    TldScanner.scan(TomcatLoader.class.getClassLoader());
+                } catch (Throwable throwable) {
+                }
+            }
+        });
+
+        for (final String className : classes) {
+            final ClassLoader loader = Warmup.class.getClassLoader();
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        Class.forName(className, true, loader);
+                    } catch (Throwable throwable) {
+                    }
+                }
+            });
+        }
+    }
+
+    private static class JaxbJavaeeLoad implements Runnable {
+
+        private final Class<?> type;
+
+        private JaxbJavaeeLoad(Class<?> type) {
+            this.type = type;
+        }
+
+        @Override
+        public void run() {
+            try {
+                JaxbJavaee.getContext(type);
+            } catch (JAXBException e) {
+            }
+        }
+    }
+
+}

Modified: openejb/trunk/openejb/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java?rev=1330257&r1=1330256&r2=1330257&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java (original)
+++ openejb/trunk/openejb/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java Wed Apr 25 13:09:40 2012
@@ -81,42 +81,6 @@ public class Container {
         Assembler.installNaming("org.apache.naming", true);
     }
 
-    static {
-        Core.warmup();
-        final ExecutorService executor = Executors.newFixedThreadPool(4, new DaemonThreadFactory("warmup"));
-
-        executor.execute(new JaxbJavaeeLoad(WebApp.class));
-//        executor.execute(new JaxbJavaeeLoad(TldTaglib.class));
-        executor.execute(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    JaxbOpenejb.getContext(Openejb.class);
-                } catch (JAXBException e) {
-                }
-            }
-        });
-        executor.execute(new JaxbJavaeeLoad(Persistence.class));
-    }
-
-
-    private static class JaxbJavaeeLoad implements Runnable {
-
-        private final Class<?> type;
-
-        private JaxbJavaeeLoad(Class<?> type) {
-            this.type = type;
-        }
-
-        @Override
-        public void run() {
-            try {
-                JaxbJavaee.getContext(type);
-            } catch (JAXBException e) {
-            }
-        }
-    }
-
     private Bootstrap bootstrap;
     protected Configuration configuration;
     private File base;

Modified: openejb/trunk/openejb/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java?rev=1330257&r1=1330256&r2=1330257&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java (original)
+++ openejb/trunk/openejb/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java Wed Apr 25 13:09:40 2012
@@ -19,22 +19,143 @@
 
 package org.apache.tomee.loader;
 
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.config.TldScanner;
+import org.apache.openejb.util.URLs;
 import org.apache.tomcat.JarScannerCallback;
+import org.apache.tomcat.util.file.Matcher;
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.scan.Constants;
 import org.apache.tomcat.util.scan.StandardJarScanner;
 
 import javax.servlet.ServletContext;
+import java.io.File;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Set;
+import java.util.StringTokenizer;
 
 public class TomEEJarScanner extends StandardJarScanner {
+
+    private static final Log log = LogFactory.getLog(StandardJarScanner.class);
+
+    private static final Set<String> defaultJarsToSkip = new HashSet<String>();
+
+    /**
+     * The string resources for this package.
+     */
+    private static final StringManager sm = StringManager.getManager(Constants.Package);
+
+    static {
+        String jarList = System.getProperty(Constants.SKIP_JARS_PROPERTY);
+        if (jarList != null) {
+            StringTokenizer tokenizer = new StringTokenizer(jarList, ",");
+            while (tokenizer.hasMoreElements()) {
+                defaultJarsToSkip.add(tokenizer.nextToken());
+            }
+        }
+    }
+
     @Override
     public void scan(ServletContext context, ClassLoader classLoader, JarScannerCallback callback, Set<String> jarsToIgnore) {
         if ("FragmentJarScannerCallback".equals(callback.getClass().getSimpleName())) {
             EmbeddedJarScanner embeddedJarScanner = new EmbeddedJarScanner();
             embeddedJarScanner.scan(context, classLoader, callback, jarsToIgnore);
+        } else if ("TldJarScannerCallback".equals(callback.getClass().getSimpleName())) {
+
+            final Set<String> ignoredJars = defaultJarsToSkip;
+
+            final Set<String[]> ignoredJarsTokens = new HashSet<String[]>();
+
+            for (String pattern : ignoredJars) {
+                ignoredJarsTokens.add(Matcher.tokenizePathAsArray(pattern));
+            }
+
+            // Scan WEB-INF/lib
+            Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
+            if (dirList != null) {
+                Iterator<String> it = dirList.iterator();
+                while (it.hasNext()) {
+                    String path = it.next();
+                    if (path.endsWith(Constants.JAR_EXT) &&
+                            !Matcher.matchPath(ignoredJarsTokens,
+                                    path.substring(path.lastIndexOf('/') + 1))) {
+                        // Need to scan this JAR
+                        URL url = null;
+                        try {
+                            // File URLs are always faster to work with so use them
+                            // if available.
+                            String realPath = context.getRealPath(path);
+                            if (realPath == null) {
+                                url = context.getResource(path);
+                            } else {
+                                url = (new File(realPath)).toURI().toURL();
+                            }
+                            process(callback, url);
+                        } catch (IOException e) {
+                            log.warn(sm.getString("jarScan.webinflibFail", url), e);
+                        }
+                    } else {
+                        if (log.isTraceEnabled()) {
+                            log.trace(sm.getString("jarScan.webinflibJarNoScan", path));
+                        }
+                    }
+                }
+            }
+
+            // Scan the classpath
+            if (isScanClassPath()) {
+                if (log.isTraceEnabled()) {
+                    log.trace(sm.getString("jarScan.classloaderStart"));
+                }
+
+
+                try {
+                    final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+                    final Set<URL> tldFileUrls = TldScanner.scan(loader);
+
+                    final Set<URL> jarUlrs = discardFilePaths(tldFileUrls);
+
+                    for (URL url : jarUlrs) {
+                        String jarName = getJarName(url);
+
+                        // Skip JARs known not to be interesting and JARs
+                        // in WEB-INF/lib we have already scanned
+                        if (jarName != null && !(Matcher.matchPath(ignoredJarsTokens, jarName) || url.toString().contains(Constants.WEB_INF_LIB + jarName))) {
+
+                            if (log.isDebugEnabled()) {
+                                log.debug(sm.getString("jarScan.classloaderJarScan", url));
+                            }
+                            try {
+                                process(callback, url);
+                            } catch (IOException ioe) {
+                                log.warn(sm.getString(
+                                        "jarScan.classloaderFail", url), ioe);
+                            }
+                        } else {
+                            if (log.isTraceEnabled()) {
+                                log.trace(sm.getString("jarScan.classloaderJarNoScan", url));
+                            }
+                        }
+                    }
+                } catch (OpenEJBException e) {
+                    log.warn("JarScan.TldScan Failed ", e);
+                }
+            }
+
         } else {
             super.scan(context, classLoader, callback, jarsToIgnore);
         }
 
+
 //        String openejbWar = System.getProperty("tomee.war");
 //
 //        if (openejbWar == null) {
@@ -60,4 +181,100 @@ public class TomEEJarScanner extends Sta
 //
 //        super.scan(context, classLoader, callback, newIgnores);
     }
+
+    private Set<URL> discardFilePaths(Set<URL> tldFileUrls) {
+        final Set<String> jarPaths = new HashSet<String>();
+
+        for (URL tldFileUrl : tldFileUrls) {
+            jarPaths.add(URLs.toFilePath(tldFileUrl));
+        }
+
+        final Set<URL> jars = new HashSet<URL>();
+        for (String jarPath : jarPaths) {
+            try {
+                final URL url = new File(jarPath).toURI().toURL();
+                jars.add(url);
+            } catch (MalformedURLException e) {
+                log.warn("Skipping JAR file " + jarPath, e);
+            }
+        }
+        return jars;
+    }
+
+    /*
+    * Scan a URL for JARs with the optional extensions to look at all files
+    * and all directories.
+    */
+    private void process(JarScannerCallback callback, URL url) throws IOException {
+
+        if (log.isTraceEnabled()) {
+            log.trace(sm.getString("jarScan.jarUrlStart", url));
+        }
+
+        final URLConnection conn = url.openConnection();
+        if (conn instanceof JarURLConnection) {
+
+            callback.scan((JarURLConnection) conn);
+
+        } else {
+
+            final String urlStr = url.toString();
+
+            if (urlStr.startsWith("file:") || urlStr.startsWith("jndi:")) {
+
+                if (urlStr.endsWith(Constants.JAR_EXT)) {
+
+                    final URL jarURL = new URL("jar:" + urlStr + "!/");
+                    callback.scan((JarURLConnection) jarURL.openConnection());
+
+                } else {
+                    try {
+
+                        final File f = new File(url.toURI());
+
+                        if (f.isFile() && isScanAllFiles()) {
+
+                            // Treat this file as a JAR
+                            final URL jarURL = new URL("jar:" + urlStr + "!/");
+                            callback.scan((JarURLConnection) jarURL.openConnection());
+
+                        } else if (f.isDirectory() && isScanAllDirectories()) {
+
+                            final File metainf = new File(f.getAbsoluteFile() + File.separator + "META-INF");
+
+                            if (metainf.isDirectory()) {
+                                callback.scan(f);
+                            }
+                        }
+                    } catch (URISyntaxException e) {
+                        // Wrap the exception and re-throw
+                        IOException ioe = new IOException();
+                        ioe.initCause(e);
+                        throw ioe;
+                    }
+                }
+            }
+        }
+
+    }
+
+    /*
+     * Extract the JAR name, if present, from a URL
+     */
+    private String getJarName(URL url) {
+
+        String name = null;
+
+        String path = url.getPath();
+        int end = path.indexOf(Constants.JAR_EXT);
+        if (end != -1) {
+            int start = path.lastIndexOf('/', end);
+            name = path.substring(start + 1, end + 4);
+        } else if (isScanAllDirectories()) {
+            int start = path.lastIndexOf('/');
+            name = path.substring(start + 1);
+        }
+
+        return name;
+    }
 }