You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2013/01/20 01:15:39 UTC

svn commit: r1435771 - in /tomee/tomee/trunk: container/openejb-core/src/main/java/org/apache/openejb/config/ tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ tomee/tomee-loader/src/main/java/org/apache/tomee/loader/

Author: rmannibucau
Date: Sun Jan 20 00:15:38 2013
New Revision: 1435771

URL: http://svn.apache.org/viewvc?rev=1435771&view=rev
Log:
trying to scan faster tlds - if it breaks too much things the breaking part should be reverted (scanner)

Modified:
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java
    tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
    tomee/tomee/trunk/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java

Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java?rev=1435771&r1=1435770&r2=1435771&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java Sun Jan 20 00:15:38 2013
@@ -1140,6 +1140,8 @@ public class DeploymentLoader implements
                 webModule.getWatchedResources().add(URLs.toFilePath(location));
             }
         }
+
+        TldScanner.clean(parentClassLoader); // no more need + this classloader is a temp one in Servlet container so avoid mem leaks
     }
 
     /**

Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java?rev=1435771&r1=1435770&r2=1435771&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java Sun Jan 20 00:15:38 2013
@@ -28,9 +28,9 @@ import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
@@ -56,27 +56,49 @@ import static org.apache.openejb.util.UR
 public class TldScanner {
 
     private static Map<ClassLoader, Set<URL>> cache = new WeakHashMap<ClassLoader, Set<URL>>();
+    private static Map<ClassLoader, Map<File, Set<URL>>> cacheByUrl = new WeakHashMap<ClassLoader, Map<File, Set<URL>>>();
+
+    public static Set<URL> scan(final ClassLoader classLoader, final File file) throws OpenEJBException {
+        scan(classLoader); // ensure init
+
+        final Map<File, Set<URL>> map = cacheByUrl.get(classLoader);
+        if (map == null || !map.containsKey(file)) {
+            return Collections.emptySet();
+        }
+        return map.get(file);
+    }
 
     public static Set<URL> scan(final ClassLoader classLoader) throws OpenEJBException {
-        if (classLoader == null) return Collections.EMPTY_SET;
+        if (classLoader == null) return Collections.emptySet();
 
         final Set<URL> urls = cache.get(classLoader);
         if (urls != null) return urls;
 
-        final Set<URL> result = scanClassLoaderForTagLibs(classLoader);
-        cache.put(classLoader, result);
+        final Map<File, Set<URL>> result = scanClassLoaderForTagLibs(classLoader);
+        cacheByUrl.put(classLoader, result);
 
-        return result;
+        final Set<URL> merged = new HashSet<URL>();
+        for (Set<URL> us : result.values()) {
+            merged.addAll(us);
+        }
+        cache.put(classLoader, merged);
+
+        return merged;
     }
 
-    public static Set<URL> scanClassLoaderForTagLibs(final ClassLoader classLoader) throws OpenEJBException {
 
-        final Set<URL> tldUrls = new HashSet<URL>();
+    public static Map<File, Set<URL>> scanClassLoaderForTagLibs(final ClassLoader classLoader) throws OpenEJBException {
+
+        final Map<File, Set<URL>> tldUrls = new HashMap<File, Set<URL>>();
 
         if (classLoader == null) return tldUrls;
         if (classLoader == Object.class.getClassLoader()) return tldUrls;
 
-        tldUrls.addAll(scan(classLoader.getParent()));
+        final ClassLoader parent = classLoader.getParent();
+        scan(parent);
+        if (cacheByUrl.containsKey(parent)) {
+            tldUrls.putAll(cacheByUrl.get(parent));
+        }
 
 
         UrlSet urlSet = new UrlSet();
@@ -103,6 +125,7 @@ public class TldScanner {
 
 
         for (URL url : urlSet.getUrls()) {
+
             if (url.getProtocol().equals("jar")) {
                 try {
                     String path = url.getPath();
@@ -128,7 +151,11 @@ public class TldScanner {
                 continue;
             }
 
-            tldUrls.addAll(scanForTagLibs(file));
+            final Set<URL> set = new HashSet<URL>();
+            set.addAll(scanForTagLibs(file));
+            if (!set.isEmpty()) {
+                tldUrls.put(file, set);
+            }
         }
 
         return tldUrls;
@@ -227,4 +254,22 @@ public class TldScanner {
 
         return urls;
     }
+
+    public static void clean(final ClassLoader loader) {
+        if (loader == null) {
+            return;
+        }
+
+        cache.remove(loader);
+        final Map<File, Set<URL>> map = cacheByUrl.remove(loader);
+        if (map != null) {
+            for (Set<URL> set : map.values()) {
+                set.clear();
+            }
+            map.clear();
+        }
+        if (loader.getParent() != TldScanner.class.getClassLoader()) { // for ears
+            clean(loader.getParent());
+        }
+    }
 }

Modified: tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1435771&r1=1435770&r2=1435771&view=diff
==============================================================================
--- tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java (original)
+++ tomee/tomee/trunk/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java Sun Jan 20 00:15:38 2013
@@ -87,6 +87,7 @@ import org.apache.openejb.cdi.CdiBuilder
 import org.apache.openejb.config.AppModule;
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.config.DeploymentLoader;
+import org.apache.openejb.config.TldScanner;
 import org.apache.openejb.config.WebModule;
 import org.apache.openejb.config.event.BeforeDeploymentEvent;
 import org.apache.openejb.config.sys.Resource;
@@ -181,6 +182,7 @@ public class TomcatWebAppBuilder impleme
     public static final String TOMEE_INIT_J2EE_INFO = "tomee.init-J2EE-info";
 
     private static final boolean FORCE_RELOADABLE = SystemInstance.get().getOptions().get("tomee.force-reloadable", false);
+    private static final boolean SKIP_TLD = SystemInstance.get().getOptions().get("tomee.skip-tld", false);
 
     private static Method getNamingContextName = null; // it just sucks but that's private
     static {
@@ -720,6 +722,9 @@ public class TomcatWebAppBuilder impleme
         if (FORCE_RELOADABLE) {
             standardContext.setReloadable(true);
         }
+        if (SKIP_TLD) {
+            standardContext.setProcessTlds(false);
+        }
 
         final String name = standardContext.getName();
 
@@ -1680,6 +1685,7 @@ public class TomcatWebAppBuilder impleme
 
         final LazyStopWebappClassLoader old = lazyClassLoader(standardContext);
         if (old != null) { // should always be the case
+            TldScanner.clean(old);
             jsfClasses.remove(old);
         }
 

Modified: tomee/tomee/trunk/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java?rev=1435771&r1=1435770&r2=1435771&view=diff
==============================================================================
--- tomee/tomee/trunk/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java (original)
+++ tomee/tomee/trunk/tomee/tomee-loader/src/main/java/org/apache/tomee/loader/TomEEJarScanner.java Sun Jan 20 00:15:38 2013
@@ -19,10 +19,14 @@
 
 package org.apache.tomee.loader;
 
+import org.apache.catalina.startup.TldConfig;
+import org.apache.catalina.startup.XmlErrorHandler;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.OpenEJBRuntimeException;
 import org.apache.openejb.config.TldScanner;
+import org.apache.openejb.loader.IO;
 import org.apache.openejb.util.URLs;
 import org.apache.tomcat.JarScannerCallback;
 import org.apache.tomcat.util.file.Matcher;
@@ -33,6 +37,9 @@ import org.apache.tomcat.util.scan.Stand
 import javax.servlet.ServletContext;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.net.JarURLConnection;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
@@ -53,6 +60,9 @@ public class TomEEJarScanner extends Sta
      */
     private static final StringManager sm = StringManager.getManager(Constants.Package);
 
+    private static final Method tldScanStream;
+    private static final Field tldConfig;
+
     static {
         final Set<String> defaultJarsToSkip = new HashSet<String>();
         final String jarList = System.getProperty(Constants.SKIP_JARS_PROPERTY);
@@ -68,6 +78,17 @@ public class TomEEJarScanner extends Sta
             ignoredJarsTokens.add(Matcher.tokenizePathAsArray(pattern));
         }
         DEFAULT_JARS_TO_SKIP = ignoredJarsTokens;
+
+        try {
+            tldScanStream = TldConfig.class.getDeclaredMethod("tldScanStream", InputStream.class);
+            tldScanStream.setAccessible(true);
+            tldConfig = TomEEJarScanner.class.getClassLoader()
+                    .loadClass("org.apache.catalina.startup.TldConfig$TldJarScannerCallback")
+                    .getDeclaredField("this$0");
+            tldConfig.setAccessible(true);
+        } catch (Exception e) {
+            throw new OpenEJBRuntimeException(e);
+        }
     }
 
     @Override
@@ -77,6 +98,16 @@ public class TomEEJarScanner extends Sta
             embeddedJarScanner.scan(context, classLoader, callback, jarsToIgnore);
         } else if ("TldJarScannerCallback".equals(callback.getClass().getSimpleName())) {
 
+            try {
+                final Set<URL> urls = TldScanner.scan(context.getClassLoader());
+                for (URL url : urls) {
+                    tldConfig(callback, url);
+                }
+                return; // done, next code is a fallback if scan() throw an exception
+            } catch (OpenEJBException oe) {
+                // no-op
+            }
+
             // Scan WEB-INF/lib
             final Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
             if (dirList != null) {
@@ -207,6 +238,35 @@ public class TomEEJarScanner extends Sta
             log.trace(sm.getString("jarScan.jarUrlStart", url));
         }
 
+        try {
+            final File file = URLs.toFile(url);
+            final Set<URL> urls = TldScanner.scan(Thread.currentThread().getContextClassLoader(), file);
+            for (URL current : urls) {
+                tldConfig(callback, current);
+            }
+        } catch (IllegalStateException e) {
+            tomcatProcess(callback, url);
+        } catch (IllegalArgumentException e) {
+            tomcatProcess(callback, url);
+        } catch (OpenEJBException e) {
+            tomcatProcess(callback, url);
+        }
+    }
+
+    private static void tldConfig(final JarScannerCallback callback, final URL current) {
+        InputStream is = null;
+        try {
+            is = current.openStream();
+            final XmlErrorHandler handler = (XmlErrorHandler) tldScanStream.invoke(tldConfig.get(callback), is);
+            handler.logFindings(log, current.toExternalForm());
+        } catch (Exception e) {
+            log.warn(sm.getString("jarScan.webinflibFail", current), e);
+        } finally {
+            IO.close(is);
+        }
+    }
+
+    private void tomcatProcess(final JarScannerCallback callback, final URL url) throws IOException {
         final URLConnection conn = url.openConnection();
         if (conn instanceof JarURLConnection) {
 
@@ -251,7 +311,6 @@ public class TomEEJarScanner extends Sta
                 }
             }
         }
-
     }
 
     /*