All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tomcat.util.scan.StandardJarScanner Maven / Gradle / Ivy

Go to download

Common code shared by Catalina and Jasper for scanning JARS and processing XML descriptors

There is a newer version: 11.0.2
Show newest version
/*
 *  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.scan;

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.URLClassLoader;
import java.net.URLConnection;
import java.util.HashSet;
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.JarScanFilter;
import org.apache.tomcat.JarScanType;
import org.apache.tomcat.JarScanner;
import org.apache.tomcat.JarScannerCallback;
import org.apache.tomcat.util.res.StringManager;

/**
 * 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:
 * 
    *
  • Scanning the classloader hierarchy (enabled by default)
  • *
  • Testing all files to see if they are JARs (disabled by default)
  • *
  • Testing all directories to see if they are exploded JARs * (disabled by default)
  • *
* All of the extensions may be controlled via configuration. */ public class StandardJarScanner implements JarScanner { private static final Log log = LogFactory.getLog(StandardJarScanner.class); /** * The string resources for this package. */ private static final StringManager sm = StringManager.getManager(Constants.Package); /** * 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; } /** * Controls the testing of the bootstrap classpath which consists of the * runtime classes provided by the JVM and any installed system extensions. */ private boolean scanBootstrapClassPath = false; public boolean isScanBootstrapClassPath() { return scanBootstrapClassPath; } public void setScanBootstrapClassPath(boolean scanBootstrapClassPath) { this.scanBootstrapClassPath = scanBootstrapClassPath; } /** * Controls the filtering of the results from the scan for JARs */ private JarScanFilter jarScanFilter = new StandardJarScanFilter(); @Override public JarScanFilter getJarScanFilter() { return jarScanFilter; } @Override public void setJarScanFilter(JarScanFilter jarScanFilter) { this.jarScanFilter = jarScanFilter; } /** * Scan the provided ServletContext and class loader for JAR files. Each JAR * file found will be passed to the callback handler to be processed. * * @param scanType The type of JAR scan to perform. This is passed to * the filter which uses it to determine how to * filter the results * @param context The ServletContext - used to locate and access * WEB-INF/lib * @param callback The handler to process any JARs found */ @Override public void scan(JarScanType scanType, ServletContext context, JarScannerCallback callback) { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.webinflibStart")); } Set processedURLs = new HashSet<>(); // Scan WEB-INF/lib Set dirList = context.getResourcePaths(Constants.WEB_INF_LIB); if (dirList != null) { Iterator it = dirList.iterator(); while (it.hasNext()) { String path = it.next(); if (path.endsWith(Constants.JAR_EXT) && getJarScanFilter().check(scanType, path.substring(path.lastIndexOf('/')+1))) { // Need to scan this JAR if (log.isDebugEnabled()) { log.debug(sm.getString("jarScan.webinflibJarScan", path)); } URL url = null; try { url = context.getResource(path); processedURLs.add(url); process(scanType, callback, url, path, true); } catch (IOException e) { log.warn(sm.getString("jarScan.webinflibFail", url), e); } } else { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.webinflibJarNoScan", path)); } } } } // Scan WEB-INF/classes if (isScanAllDirectories()) { try { URL url = context.getResource("/WEB-INF/classes/META-INF"); if (url != null) { // Class path scanning will look at WEB-INF/classes since // that is the URL that Tomcat's web application class // loader returns. Therefore, it is this URL that needs to // be added to the set of processed URLs. URL webInfURL = context.getResource("/WEB-INF/classes"); if (webInfURL != null) { processedURLs.add(webInfURL); } try { callback.scanWebInfClasses(); } catch (IOException e) { log.warn(sm.getString("jarScan.webinfclassesFail"), e); } } } catch (MalformedURLException e) { // Ignore } } // Scan the classpath if (isScanClassPath()) { if (log.isTraceEnabled()) { log.trace(sm.getString("jarScan.classloaderStart")); } ClassLoader stopLoader = null; if (!isScanBootstrapClassPath()) { // Stop when we reach the bootstrap class loader stopLoader = ClassLoader.getSystemClassLoader().getParent(); } ClassLoader classLoader = context.getClassLoader(); // JARs are treated as application provided until the common class // loader is reached. boolean isWebapp = true; while (classLoader != null && classLoader != stopLoader) { if (classLoader instanceof URLClassLoader) { if (isWebapp) { isWebapp = isWebappClassLoader(classLoader); } URL[] urls = ((URLClassLoader) classLoader).getURLs(); for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy