tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rj...@apache.org
Subject svn commit: r981967 - in /tomcat/trunk: conf/catalina.properties java/org/apache/tomcat/util/file/ java/org/apache/tomcat/util/file/Matcher.java java/org/apache/tomcat/util/scan/StandardJarScanner.java webapps/docs/changelog.xml
Date Tue, 03 Aug 2010 17:09:55 GMT
Author: rjung
Date: Tue Aug  3 17:09:55 2010
New Revision: 981967

URL: http://svn.apache.org/viewvc?rev=981967&view=rev
Log:
Allow glob patterns in the jarsToSkip configuration and add
some debug logging to the jar scanner.

Still need to localize debug log messages.
ecj Jar in catalina.properties now uses a glob,
did not yet add globs to all the commons jars
in the default configuration.

Added:
    tomcat/trunk/java/org/apache/tomcat/util/file/
    tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java   (with props)
Modified:
    tomcat/trunk/conf/catalina.properties
    tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/conf/catalina.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/conf/catalina.properties?rev=981967&r1=981966&r2=981967&view=diff
==============================================================================
--- tomcat/trunk/conf/catalina.properties (original)
+++ tomcat/trunk/conf/catalina.properties Tue Aug  3 17:09:55 2010
@@ -89,7 +89,7 @@ tomcat.util.scan.DefaultJarScanner.jarsT
 bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,\
 annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,\
 catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-tribes.jar,\
-jasper.jar,jasper-el.jar,ecj-3.6.jar,\
+jasper.jar,jasper-el.jar,ecj-*.jar,\
 tomcat-api.jar,tomcat-util.jar,tomcat-coyote.jar,tomcat-dbcp.jar,\
 tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,\
 commons-beanutils.jar,commons-collections.jar,commons-dbcp.jar,\

Added: tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java?rev=981967&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java Tue Aug  3 17:09:55 2010
@@ -0,0 +1,571 @@
+/*
+ *  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.tomcat.util.file;
+
+import java.io.File;
+import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * <p>This is a utility class used by selectors and DirectoryScanner. The
+ * functionality more properly belongs just to selectors, but unfortunately
+ * DirectoryScanner exposed these as protected methods. Thus we have to
+ * support any subclasses of DirectoryScanner that may access these methods.
+ * </p>
+ * <p>This is a Singleton.</p>
+ */
+public final class Matcher {
+
+    /**
+     * The pattern that matches an arbitrary number of directories.
+     */
+    public static final String DEEP_TREE_MATCH = "**";
+
+    private static final Matcher instance = new Matcher();
+    private static final String OS_NAME =
+        System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
+    private static final String PATH_SEP =
+        System.getProperty("path.separator");
+    private static final boolean ON_NETWARE = isNetware();
+    private static final boolean ON_DOS = isDos();
+
+    /**
+     * Private Constructor
+     */
+    private Matcher() {
+    }
+
+    /**
+     * Retrieves the instance of the Singleton.
+     * @return singleton instance
+     */
+    public static Matcher getInstance() {
+        return instance;
+    }
+
+    /**
+     * Tests whether or not a given path matches any pattern in the given set.
+     *
+     * If you need to call this method multiple times with the same 
+     * pattern you should rather use TokenizedPath
+     *
+     * @see TokenizedPath
+     * 
+     * @param patternSet The pattern set to match against. Must not be
+     *                <code>null</code>.
+     * @param str     The path to match, as a String. Must not be
+     *                <code>null</code>.
+     *
+     * @return <code>true</code> if any pattern in the set matches against the
string,
+     *         or <code>false</code> otherwise.
+     */
+    public static boolean matchPath(Set<String[]> patternSet, String str) {
+        boolean result;
+        for (String[] patternTokens: patternSet) {
+            if (matchPath(patternTokens, tokenizePathAsArray(str), true)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether or not a given path matches a given pattern.
+     *
+     * If you need to call this method multiple times with the same 
+     * pattern you should rather use TokenizedPath
+     *
+     * @see TokenizedPath
+     * 
+     * @param pattern The pattern to match against. Must not be
+     *                <code>null</code>.
+     * @param str     The path to match, as a String. Must not be
+     *                <code>null</code>.
+     *
+     * @return <code>true</code> if the pattern matches against the string,
+     *         or <code>false</code> otherwise.
+     */
+    public static boolean matchPath(String pattern, String str) {
+        String[] patDirs = tokenizePathAsArray(pattern);
+        return matchPath(patDirs, tokenizePathAsArray(str), true);
+    }
+
+    /**
+     * Tests whether or not a given path matches a given pattern.
+     * 
+     * If you need to call this method multiple times with the same 
+     * pattern you should rather use TokenizedPattern
+     *
+     * @see TokenizedPattern
+     * 
+     * @param pattern The pattern to match against. Must not be
+     *                <code>null</code>.
+     * @param str     The path to match, as a String. Must not be
+     *                <code>null</code>.
+     * @param isCaseSensitive Whether or not matching should be performed
+     *                        case sensitively.
+     *
+     * @return <code>true</code> if the pattern matches against the string,
+     *         or <code>false</code> otherwise.
+     */
+    public static boolean matchPath(String pattern, String str,
+                                    boolean isCaseSensitive) {
+        String[] patDirs = tokenizePathAsArray(pattern);
+        return matchPath(patDirs, tokenizePathAsArray(str), isCaseSensitive);
+    }
+
+    /**
+     * Core implementation of matchPath.  It is isolated so that it
+     * can be called from TokenizedPattern.
+     */
+    static boolean matchPath(String[] tokenizedPattern, String[] strDirs,
+                             boolean isCaseSensitive) {
+        int patIdxStart = 0;
+        int patIdxEnd = tokenizedPattern.length - 1;
+        int strIdxStart = 0;
+        int strIdxEnd = strDirs.length - 1;
+
+        // up to first '**'
+        while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+            String patDir = tokenizedPattern[patIdxStart];
+            if (patDir.equals(DEEP_TREE_MATCH)) {
+                break;
+            }
+            if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
+                return false;
+            }
+            patIdxStart++;
+            strIdxStart++;
+        }
+        if (strIdxStart > strIdxEnd) {
+            // String is exhausted
+            for (int i = patIdxStart; i <= patIdxEnd; i++) {
+                if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            if (patIdxStart > patIdxEnd) {
+                // String not exhausted, but pattern is. Failure.
+                return false;
+            }
+        }
+
+        // up to last '**'
+        while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+            String patDir = tokenizedPattern[patIdxEnd];
+            if (patDir.equals(DEEP_TREE_MATCH)) {
+                break;
+            }
+            if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
+                return false;
+            }
+            patIdxEnd--;
+            strIdxEnd--;
+        }
+        if (strIdxStart > strIdxEnd) {
+            // String is exhausted
+            for (int i = patIdxStart; i <= patIdxEnd; i++) {
+                if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+            int patIdxTmp = -1;
+            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+                if (tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+                    patIdxTmp = i;
+                    break;
+                }
+            }
+            if (patIdxTmp == patIdxStart + 1) {
+                // '**/**' situation, so skip one
+                patIdxStart++;
+                continue;
+            }
+            // Find the pattern between padIdxStart & padIdxTmp in str between
+            // strIdxStart & strIdxEnd
+            int patLength = (patIdxTmp - patIdxStart - 1);
+            int strLength = (strIdxEnd - strIdxStart + 1);
+            int foundIdx = -1;
+            strLoop:
+                        for (int i = 0; i <= strLength - patLength; i++) {
+                            for (int j = 0; j < patLength; j++) {
+                                String subPat = tokenizedPattern[patIdxStart + j + 1];
+                                String subStr = strDirs[strIdxStart + i + j];
+                                if (!match(subPat, subStr, isCaseSensitive)) {
+                                    continue strLoop;
+                                }
+                            }
+
+                            foundIdx = strIdxStart + i;
+                            break;
+                        }
+
+            if (foundIdx == -1) {
+                return false;
+            }
+
+            patIdxStart = patIdxTmp;
+            strIdxStart = foundIdx + patLength;
+        }
+
+        for (int i = patIdxStart; i <= patIdxEnd; i++) {
+            if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Tests whether or not a string matches against a pattern.
+     * The pattern may contain two special characters:<br>
+     * '*' means zero or more characters<br>
+     * '?' means one and only one character
+     *
+     * @param pattern The pattern to match against.
+     *                Must not be <code>null</code>.
+     * @param str     The string which must be matched against the pattern.
+     *                Must not be <code>null</code>.
+     *
+     * @return <code>true</code> if the string matches against the pattern,
+     *         or <code>false</code> otherwise.
+     */
+    public static boolean match(String pattern, String str) {
+        return match(pattern, str, true);
+    }
+
+    /**
+     * Tests whether or not a string matches against a pattern.
+     * The pattern may contain two special characters:<br>
+     * '*' means zero or more characters<br>
+     * '?' means one and only one character
+     *
+     * @param pattern The pattern to match against.
+     *                Must not be <code>null</code>.
+     * @param str     The string which must be matched against the pattern.
+     *                Must not be <code>null</code>.
+     * @param caseSensitive Whether or not matching should be performed
+     *                        case sensitively.
+     *
+     *
+     * @return <code>true</code> if the string matches against the pattern,
+     *         or <code>false</code> otherwise.
+     */
+    public static boolean match(String pattern, String str,
+                                boolean caseSensitive) {
+        char[] patArr = pattern.toCharArray();
+        char[] strArr = str.toCharArray();
+        int patIdxStart = 0;
+        int patIdxEnd = patArr.length - 1;
+        int strIdxStart = 0;
+        int strIdxEnd = strArr.length - 1;
+        char ch;
+
+        boolean containsStar = false;
+        for (int i = 0; i < patArr.length; i++) {
+            if (patArr[i] == '*') {
+                containsStar = true;
+                break;
+            }
+        }
+
+        if (!containsStar) {
+            // No '*'s, so we make a shortcut
+            if (patIdxEnd != strIdxEnd) {
+                return false; // Pattern and string do not have the same size
+            }
+            for (int i = 0; i <= patIdxEnd; i++) {
+                ch = patArr[i];
+                if (ch != '?') {
+                    if (different(caseSensitive, ch, strArr[i])) {
+                        return false; // Character mismatch
+                    }
+                }
+            }
+            return true; // String matches against pattern
+        }
+
+        if (patIdxEnd == 0) {
+            return true; // Pattern contains only '*', which matches anything
+        }
+
+        // Process characters before first star
+        while (true) {
+            ch = patArr[patIdxStart];
+            if (ch == '*' || strIdxStart > strIdxEnd) {
+                break;
+            }
+            if (ch != '?') {
+                if (different(caseSensitive, ch, strArr[strIdxStart])) {
+                    return false; // Character mismatch
+                }
+            }
+            patIdxStart++;
+            strIdxStart++;
+        }
+        if (strIdxStart > strIdxEnd) {
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            return allStars(patArr, patIdxStart, patIdxEnd);
+        }
+
+        // Process characters after last star
+        while (true) {
+            ch = patArr[patIdxEnd];
+            if (ch == '*' || strIdxStart > strIdxEnd) {
+                break;
+            }
+            if (ch != '?') {
+                if (different(caseSensitive, ch, strArr[strIdxEnd])) {
+                    return false; // Character mismatch
+                }
+            }
+            patIdxEnd--;
+            strIdxEnd--;
+        }
+        if (strIdxStart > strIdxEnd) {
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            return allStars(patArr, patIdxStart, patIdxEnd);
+        }
+
+        // process pattern between stars. padIdxStart and patIdxEnd point
+        // always to a '*'.
+        while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+            int patIdxTmp = -1;
+            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+                if (patArr[i] == '*') {
+                    patIdxTmp = i;
+                    break;
+                }
+            }
+            if (patIdxTmp == patIdxStart + 1) {
+                // Two stars next to each other, skip the first one.
+                patIdxStart++;
+                continue;
+            }
+            // Find the pattern between padIdxStart & padIdxTmp in str between
+            // strIdxStart & strIdxEnd
+            int patLength = (patIdxTmp - patIdxStart - 1);
+            int strLength = (strIdxEnd - strIdxStart + 1);
+            int foundIdx = -1;
+            strLoop:
+            for (int i = 0; i <= strLength - patLength; i++) {
+                for (int j = 0; j < patLength; j++) {
+                    ch = patArr[patIdxStart + j + 1];
+                    if (ch != '?') {
+                        if (different(caseSensitive, ch,
+                                      strArr[strIdxStart + i + j])) {
+                            continue strLoop;
+                        }
+                    }
+                }
+
+                foundIdx = strIdxStart + i;
+                break;
+            }
+
+            if (foundIdx == -1) {
+                return false;
+            }
+
+            patIdxStart = patIdxTmp;
+            strIdxStart = foundIdx + patLength;
+        }
+
+        // All characters in the string are used. Check if only '*'s are left
+        // in the pattern. If so, we succeeded. Otherwise failure.
+        return allStars(patArr, patIdxStart, patIdxEnd);
+    }
+
+    private static boolean allStars(char[] chars, int start, int end) {
+        for (int i = start; i <= end; ++i) {
+            if (chars[i] != '*') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean different(
+        boolean caseSensitive, char ch, char other) {
+        return caseSensitive
+            ? ch != other
+            : Character.toUpperCase(ch) != Character.toUpperCase(other);
+    }
+
+    /**
+     * Breaks a path up into a Vector of path elements, tokenizing on
+     * <code>File.separator</code>.
+     *
+     * @param path Path to tokenize. Must not be <code>null</code>.
+     *
+     * @return a String array of path elements from the tokenized path
+     */
+    public static String[] tokenizePathAsArray(String path) {
+        String root = null;
+        if (isAbsolutePath(path)) {
+            String[] s = dissect(path);
+            root = s[0];
+            path = s[1];
+        }
+        char sep = File.separatorChar;
+        int start = 0;
+        int len = path.length();
+        int count = 0;
+        for (int pos = 0; pos < len; pos++) {
+            if (path.charAt(pos) == sep) {
+                if (pos != start) {
+                    count++;
+                }
+                start = pos + 1;
+            }
+        }
+        if (len != start) {
+            count++;
+        }
+        String[] l = new String[count + ((root == null) ? 0 : 1)];
+
+        if (root != null) {
+            l[0] = root;
+            count = 1;
+        } else {
+            count = 0;
+        }
+        start = 0;
+        for (int pos = 0; pos < len; pos++) {
+            if (path.charAt(pos) == sep) {
+                if (pos != start) {
+                    String tok = path.substring(start, pos);
+                    l[count++] = tok;
+                }
+                start = pos + 1;
+            }
+        }
+        if (len != start) {
+            String tok = path.substring(start);
+            l[count/*++*/] = tok;
+        }
+        return l;
+    }
+
+    /**
+     * Dissect the specified absolute path.
+     * @param path the path to dissect (must be absolute).
+     * @return String[] {root, remaining path}.
+     * @throws java.lang.NullPointerException if path is null.
+     */
+    private static String[] dissect(String path) {
+        char sep = File.separatorChar;
+        path = path.replace('/', sep).replace('\\', sep);
+
+        String root = null;
+        int colon = path.indexOf(':');
+        if (colon > 0 && (ON_DOS || ON_NETWARE)) {
+
+            int next = colon + 1;
+            root = path.substring(0, next);
+            char[] ca = path.toCharArray();
+            root += sep;
+            //remove the initial separator; the root has it.
+            next = (ca[next] == sep) ? next + 1 : next;
+
+            StringBuffer sbPath = new StringBuffer();
+            // Eliminate consecutive slashes after the drive spec:
+            for (int i = next; i < ca.length; i++) {
+                if (ca[i] != sep || ca[i - 1] != sep) {
+                    sbPath.append(ca[i]);
+                }
+            }
+            path = sbPath.toString();
+        } else if (path.length() > 1 && path.charAt(1) == sep) {
+            // UNC drive
+            int nextsep = path.indexOf(sep, 2);
+            nextsep = path.indexOf(sep, nextsep + 1);
+            root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
+            path = path.substring(root.length());
+        } else {
+            root = File.separator;
+            path = path.substring(1);
+        }
+        return new String[] {root, path};
+    }
+
+    /**
+     * Verifies that the specified filename represents an absolute path.
+     * Differs from new java.io.File("filename").isAbsolute() in that a path
+     * beginning with a double file separator--signifying a Windows UNC--must
+     * at minimum match "\\a\b" to be considered an absolute path.
+     * @param filename the filename to be checked.
+     * @return true if the filename represents an absolute path.
+     * @throws java.lang.NullPointerException if filename is null.
+     */
+    private static boolean isAbsolutePath(String filename) {
+        int len = filename.length();
+        if (len == 0) {
+            return false;
+        }
+        char sep = File.separatorChar;
+        filename = filename.replace('/', sep).replace('\\', sep);
+        char c = filename.charAt(0);
+        if (!(ON_DOS || ON_NETWARE)) {
+            return (c == sep);
+        }
+        if (c == sep) {
+            // CheckStyle:MagicNumber OFF
+            if (!(ON_DOS && len > 4 && filename.charAt(1) == sep)) {
+                return false;
+            }
+            // CheckStyle:MagicNumber ON
+            int nextsep = filename.indexOf(sep, 2);
+            return nextsep > 2 && nextsep + 1 < len;
+        }
+        int colon = filename.indexOf(':');
+        return (Character.isLetter(c) && colon == 1
+                && filename.length() > 2 && filename.charAt(2) == sep)
+                || (ON_NETWARE && colon > 0);
+    }
+
+    /**
+     * Determines if our OS is Netware.
+     *
+     * @return true if we run on Netware
+     */
+    private static boolean isNetware() {
+        return OS_NAME.indexOf("netware") > -1;
+    }
+
+    /**
+     * Determines if our OS is DOS.
+     *
+     * @return true if we run on DOS
+     */
+    private static boolean isDos() {
+        return PATH_SEP.equals(";") && !isNetware();
+    }
+}

Propchange: tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/java/org/apache/tomcat/util/file/Matcher.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java?rev=981967&r1=981966&r2=981967&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java Tue Aug  3 17:09:55
2010
@@ -35,6 +35,7 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.JarScanner;
 import org.apache.tomcat.JarScannerCallback;
+import org.apache.tomcat.util.file.Matcher;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -134,6 +135,13 @@ public class StandardJarScanner implemen
         } else {
             ignoredJars = jarsToSkip;
         }
+        Set<String[]> ignoredJarsTokens = new HashSet<String[]>();
+        for (String pattern: ignoredJars) {
+            if (log.isDebugEnabled()) {
+                log.debug("Tokenizing " + pattern);
+            }
+            ignoredJarsTokens.add(Matcher.tokenizePathAsArray(pattern));
+        }
 
         // Scan WEB-INF/lib
         Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
@@ -141,10 +149,16 @@ public class StandardJarScanner implemen
             Iterator<String> it = dirList.iterator();
             while (it.hasNext()) {
                 String path = it.next();
+                if (log.isDebugEnabled()) {
+                    log.debug("Matching path '" + path + "'");
+                }
                 if (path.endsWith(Constants.JAR_EXT) &&
-                        !ignoredJars.contains(
-                                path.substring(path.lastIndexOf('/')+1))) {
+                        !Matcher.matchPath(ignoredJarsTokens,
+                            path.substring(path.lastIndexOf('/')+1))) {
                     // Need to scan this JAR
+                    if (log.isDebugEnabled()) {
+                        log.debug("Scanning jar " + path);
+                    }
                     URL url = null;
                     try {
                         url = context.getResource(path);
@@ -152,6 +166,10 @@ public class StandardJarScanner implemen
                     } catch (IOException e) {
                         log.warn(sm.getString("jarScan.webinflibFail", url), e);
                     }
+                } else {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Didn't scan jar " + path);
+                    }
                 }
             }
         }
@@ -174,15 +192,26 @@ public class StandardJarScanner implemen
                         
                         // Skip JARs with known not to be interesting and JARs
                         // in WEB-INF/lib we have already scanned
-                        if (!(ignoredJars.contains(jarName) ||
+                        if (log.isDebugEnabled()) {
+                            log.debug("Matching jar '" + jarName + "'");
+                        }
+                        if (jarName != null &&
+                            !(Matcher.matchPath(ignoredJarsTokens, jarName) ||
                                 urls[i].toString().contains(
                                         Constants.WEB_INF_LIB + jarName))) {
+                            if (log.isDebugEnabled()) {
+                                log.debug("Scanning jar " + jarName);
+                            }
                             try {
                                 process(callback, urls[i]);
                             } catch (IOException ioe) {
                                 log.warn(sm.getString(
                                         "jarScan.classloaderFail",urls[i]), ioe);
                             }
+                        } else {
+                            if (log.isDebugEnabled()) {
+                                log.debug("Didn't scan jar " + jarName);
+                            }
                         }
                     }
                 }

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=981967&r1=981966&r2=981967&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Aug  3 17:09:55 2010
@@ -42,6 +42,10 @@
         Fix repgrssion that prevented running with a security manager enabled.
         (markt)
       </fix>
+      <update>
+        Allow glob patterns in the <code>jarsToSkip</code> configuration and
add
+        some debug logging to the jar scanner. (rjung)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Web applications">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message