From 29357a55f48e80cb80d4a2f17adde333857e36a8 Mon Sep 17 00:00:00 2001 From: markt Date: Mon, 14 Dec 2009 21:12:35 +0000 Subject: [PATCH] Fix TLD scanning in JARs for JspC. This copies the DefaultJarScanner from Tomcat. Less invasive than the alternative refactoring that will have to wait for another day. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@890479 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/startup/DefaultJarScanner.java | 2 + .../apache/jasper/compiler/InternalJarScanner.java | 236 +++++++++++++++++++++ .../apache/jasper/compiler/JarScannerFactory.java | 5 +- .../jasper/resources/LocalStrings.properties | 7 +- 4 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 java/org/apache/jasper/compiler/InternalJarScanner.java diff --git a/java/org/apache/catalina/startup/DefaultJarScanner.java b/java/org/apache/catalina/startup/DefaultJarScanner.java index 87623b903..331eee536 100644 --- a/java/org/apache/catalina/startup/DefaultJarScanner.java +++ b/java/org/apache/catalina/startup/DefaultJarScanner.java @@ -48,6 +48,8 @@ import org.apache.tomcat.util.res.StringManager; * (disabled by default) * * All of the extensions may be controlled via configuration. + * + * Keep in sync with org.apache.jasper.compiler.InternalJarScanner */ public class DefaultJarScanner implements JarScanner { diff --git a/java/org/apache/jasper/compiler/InternalJarScanner.java b/java/org/apache/jasper/compiler/InternalJarScanner.java new file mode 100644 index 000000000..20feea657 --- /dev/null +++ b/java/org/apache/jasper/compiler/InternalJarScanner.java @@ -0,0 +1,236 @@ +/* + * 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.jasper.compiler; + +import java.io.File; +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.util.Iterator; +import java.util.Set; + +import javax.servlet.ServletContext; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.JarScanner; +import org.apache.tomcat.JarScannerCallback; + +/** + * The default {@link JarScanner} implementation scans the WEB-INF/lib directory + * followed by the provided classloader and then works up the classloader + * hierarchy. This implementation is sufficient to meet the requirements of the + * Servlet 3.0 specification as well as to provide a number of Tomcat specific + * extensions. The extensions are: + * + * All of the extensions may be controlled via configuration. + * + * Keep in sync with org.apache.catalina.startup.DefaultJarScanner + */ +public class InternalJarScanner implements JarScanner { + + private static final String JAR_EXT = ".jar"; + private static final String WEB_INF_LIB = "/WEB-INF/lib/"; + + private static final Log log = LogFactory.getLog(InternalJarScanner.class); + + /** + * Controls the classpath scanning extension. + */ + private boolean scanClassPath = true; + public boolean isScanClassPath() { + return scanClassPath; + } + public void setScanClassPath(boolean scanClassPath) { + this.scanClassPath = scanClassPath; + } + + /** + * Controls the testing all files to see of they are JAR files extension. + */ + private boolean scanAllFiles = false; + public boolean isScanAllFiles() { + return scanAllFiles; + } + public void setScanAllFiles(boolean scanAllFiles) { + this.scanAllFiles = scanAllFiles; + } + + /** + * Controls the testing all directories to see of they are exploded JAR + * files extension. + */ + private boolean scanAllDirectories = false; + public boolean isScanAllDirectories() { + return scanAllDirectories; + } + public void setScanAllDirectories(boolean scanAllDirectories) { + this.scanAllDirectories = scanAllDirectories; + } + + /** + * {@inheritDoc} + */ + @Override + public void scan(ServletContext context, ClassLoader classloader, + JarScannerCallback callback, Set jarsToSkip) { + + if (log.isTraceEnabled()) { + log.trace(Localizer.getMessage("jsp.jarScan.webinflibStart")); + } + + // Scan WEB-INF/lib + Set dirList = context.getResourcePaths(WEB_INF_LIB); + if (dirList != null) { + Iterator it = dirList.iterator(); + while (it.hasNext()) { + String path = it.next(); + if (path.endsWith(JAR_EXT) && + !jarsToSkip.contains( + path.substring(path.lastIndexOf('/')))) { + // Need to scan this JAR + URL url = null; + try { + url = context.getResource(path); + process(callback, url); + } catch (IOException e) { + if (url == null) { + log.warn(Localizer.getMessage( + "jsp.jarScan.webinflibFail", + path), e); + } else { + log.warn(Localizer.getMessage( + "jsp.jarScan.webinflibFail", + url.toString()), e); + } + } + } + } + } + + // Scan the classpath + if (scanClassPath) { + if (log.isTraceEnabled()) { + log.trace(Localizer.getMessage("jsp.jarScan.classloaderStart")); + } + + ClassLoader loader = + Thread.currentThread().getContextClassLoader(); + + while (loader != null) { + if (loader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader) loader).getURLs(); + for (int i=0; i