Author: markt Date: Wed Jul 31 13:13:10 2013 New Revision: 1508845 URL: http://svn.apache.org/r1508845 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55312 Ensure that class path entries representing directories are always scanned for matches to @HandlesTypes
Modified: tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java tomcat/trunk/webapps/docs/config/jar-scan-filter.xml tomcat/trunk/webapps/docs/config/jar-scanner.xml 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=1508845&r1=1508844&r2=1508845&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java Wed Jul 31 13:13:10 2013 @@ -162,7 +162,7 @@ public class StandardJarScanner implemen } else { url = (new File(realPath)).toURI().toURL(); } - process(callback, url, true); + process(scanType, callback, url, true); } catch (IOException e) { log.warn(sm.getString("jarScan.webinflibFail", url), e); } @@ -219,24 +219,34 @@ public class StandardJarScanner implemen } URL[] urls = ((URLClassLoader) classLoader).getURLs(); for (int i=0; i<urls.length; i++) { - // Extract the jarName if there is one to be found - String jarName = getJarName(urls[i]); + ClassPathEntry cpe = new ClassPathEntry(urls[i]); - // Skip JARs known not to be interesting - if (jarName != null && - jarScanFilter.check(scanType, jarName)) { + // JARs are scanned unless the filter says not to. + // Directories are scanned for pluggability scans or + // if scanAllDirectories is enabled unless the + // filter says not to. + if ((cpe.isJar() || + scanType == JarScanType.PLUGGABILITY || + isScanAllDirectories()) && + jarScanFilter.check(scanType, + cpe.getName())) { if (log.isDebugEnabled()) { - log.debug(sm.getString("jarScan.classloaderJarScan", urls[i])); + log.debug(sm.getString( + "jarScan.classloaderJarScan", urls[i])); } try { - process(callback, urls[i], isWebapp); + process(scanType, callback, urls[i], isWebapp); } catch (IOException ioe) { log.warn(sm.getString( - "jarScan.classloaderFail",urls[i]), ioe); + "jarScan.classloaderFail", urls[i]), + ioe); } } else { + // JAR / directory has been skipped if (log.isTraceEnabled()) { - log.trace(sm.getString("jarScan.classloaderJarNoScan", urls[i])); + log.trace(sm.getString( + "jarScan.classloaderJarNoScan", + urls[i])); } } } @@ -278,8 +288,8 @@ public class StandardJarScanner implemen * Scan a URL for JARs with the optional extensions to look at all files * and all directories. */ - private void process(JarScannerCallback callback, URL url, boolean isWebapp) - throws IOException { + private void process(JarScanType scanType, JarScannerCallback callback, + URL url, boolean isWebapp) throws IOException { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.jarUrlStart", url)); @@ -306,11 +316,15 @@ public class StandardJarScanner implemen callback.scan( (JarURLConnection) jarURL.openConnection(), isWebapp); - } else if (f.isDirectory() && scanAllDirectories) { - File metainf = new File(f.getAbsoluteFile() + - File.separator + "META-INF"); - if (metainf.isDirectory()) { + } else if (f.isDirectory()) { + if (scanType == JarScanType.PLUGGABILITY) { callback.scan(f, isWebapp); + } else { + File metainf = new File(f.getAbsoluteFile() + + File.separator + "META-INF"); + if (metainf.isDirectory()) { + callback.scan(f, isWebapp); + } } } } catch (URISyntaxException e) { @@ -325,24 +339,36 @@ public class StandardJarScanner implemen } - /* - * Extract the JAR name, if present, from a URL - */ - private String getJarName(URL url) { - String name = null; + private static class ClassPathEntry { + + private final boolean jar; + private final String name; + + public ClassPathEntry(URL url) { + String path = url.getPath(); + int end = path.indexOf(Constants.JAR_EXT); + if (end != -1) { + jar = true; + int start = path.lastIndexOf('/', end); + name = path.substring(start + 1, end + 4); + } else { + jar = false; + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + int start = path.lastIndexOf('/'); + name = path.substring(start + 1); + } + + } - 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); + public boolean isJar() { + return jar; } - return name; + public String getName() { + return name; + } } - } Modified: tomcat/trunk/webapps/docs/config/jar-scan-filter.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/jar-scan-filter.xml?rev=1508845&r1=1508844&r2=1508845&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/jar-scan-filter.xml (original) +++ tomcat/trunk/webapps/docs/config/jar-scan-filter.xml Wed Jul 31 13:13:10 2013 @@ -78,17 +78,17 @@ <attributes> <attribute name="tldSkip" required="false"> - <p>The comma separated list of JAR file name patterns to skip when - scanning for TLDs. If not specified, the default is obtained from the - <code>tomcat.util.scan.StandardJarScanFilter.jarsToSkip</code> system - property.</p> + <p>The comma separated list of JAR file and / or directory name patterns + to skip when scanning for TLDs. If not specified, the default is obtained + from the <code>tomcat.util.scan.StandardJarScanFilter.jarsToSkip</code> + system property.</p> </attribute> <attribute name="tldScan" required="false"> - <p>The comma separated list of JAR file name patterns to scan when - scanning for TLDs. If not specified, the default is obtained from the - <code>tomcat.util.scan.StandardJarScanFilter.jarsToScan</code> system - property.</p> + <p>The comma separated list of JAR file and / or directory name patterns + to scan when scanning for TLDs. If not specified, the default is obtained + from the <code>tomcat.util.scan.StandardJarScanFilter.jarsToScan</code> + system property.</p> </attribute> <attribute name="defaultTldScan" required="false"> @@ -101,17 +101,17 @@ </attribute> <attribute name="pluggableSkip" required="false"> - <p>The comma separated list of JAR file name patterns to skip when - scanning for pluggable features. If not specified, the default is - obtained from the + <p>The comma separated list of JAR file and / or directory name patterns + to skip when scanning for pluggable features. If not specified, the + default is obtained from the <code>tomcat.util.scan.StandardJarScanFilter.jarsToSkip</code> system property.</p> </attribute> <attribute name="pluggableScan" required="false"> - <p>The comma separated list of JAR file name patterns to scan when - scanning for pluggable features. If not specified, the default is - obtained from the + <p>The comma separated list of JAR file and / or directory name patterns + to scan when scanning for pluggable features. If not specified, the + default is obtained from the <code>tomcat.util.scan.StandardJarScanFilter.jarsToScan</code> system property.</p> </attribute> Modified: tomcat/trunk/webapps/docs/config/jar-scanner.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/jar-scanner.xml?rev=1508845&r1=1508844&r2=1508845&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/jar-scanner.xml (original) +++ tomcat/trunk/webapps/docs/config/jar-scanner.xml Wed Jul 31 13:13:10 2013 @@ -35,10 +35,10 @@ <section name="Introduction"> <p>The <strong>Jar Scanner</strong> element represents the component that is - used to scan the web application for JAR files. It is typically used during - web application start to identify configuration files such as TLDs or - web-fragment.xml files that must be processed as part of the web application - initialisation.</p> + used to scan the web application for JAR files and directories of class files. + It is typically used during web application start to identify configuration + files such as TLDs or web-fragment.xml files that must be processed as part of + the web application initialisation.</p> <p>A Jar Scanner element MAY be nested inside a <a href="context.html">Context</a> component. If it is not included, @@ -79,10 +79,13 @@ <attribute name="scanAllDirectories" required="false"> <p>If true, any directories found on the classpath will be checked to see - if are expanded Jar files. The default is <code>false</code>. Tomcat + if are expanded JAR files. The default is <code>false</code>. Tomcat determines if directory is an expanded JAR file by looking for a META-INF sub-directory. Only if the META-INF sub-directory exists, is the - directory to be an expanded JAR file.</p> + directory assumed to be an expanded JAR file. Note that for scans for + matches to <code>@HandlesTypes</code> annotations, all directories will + be scanned irrespective of the presence or not of a META-INF + sub-directory.</p> </attribute> <attribute name="scanAllFiles" required="false"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org