You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/10/05 19:02:06 UTC

svn commit: r1811229 - /tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java

Author: markt
Date: Thu Oct  5 19:02:06 2017
New Revision: 1811229

URL: http://svn.apache.org/viewvc?rev=1811229&view=rev
Log:
Start to improved Java 9 JAR scanning
Make StandardJarScanner easier to extend

Modified:
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java

Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java?rev=1811229&r1=1811228&r2=1811229&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java Thu Oct  5 19:02:06 2017
@@ -26,7 +26,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Deque;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Set;
 import java.util.jar.Attributes;
@@ -43,6 +42,7 @@ import org.apache.tomcat.JarScanner;
 import org.apache.tomcat.JarScannerCallback;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.buf.UriUtil;
+import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -176,9 +176,7 @@ public class StandardJarScanner implemen
         // Scan WEB-INF/lib
         Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
         if (dirList != null) {
-            Iterator<String> it = dirList.iterator();
-            while (it.hasNext()) {
-                String path = it.next();
+            for (String path : dirList) {
                 if (path.endsWith(Constants.JAR_EXT) &&
                         getJarScanFilter().check(scanType,
                                 path.substring(path.lastIndexOf('/')+1))) {
@@ -228,76 +226,106 @@ public class StandardJarScanner implemen
 
         // Scan the classpath
         if (isScanClassPath()) {
-            if (log.isTraceEnabled()) {
-                log.trace(sm.getString("jarScan.classloaderStart"));
-            }
+            doScanClassPath(scanType, context, callback, processedURLs);
+        }
+    }
 
-            ClassLoader stopLoader = null;
-            if (!isScanBootstrapClassPath()) {
-                // Stop when we reach the bootstrap class loader
-                stopLoader = ClassLoader.getSystemClassLoader().getParent();
-            }
 
-            ClassLoader classLoader = context.getClassLoader();
+    protected void doScanClassPath(JarScanType scanType, ServletContext context,
+            JarScannerCallback callback, Set<URL> processedURLs) {
+        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);
+                }
+
+                // Use a Deque so URLs can be removed as they are processed
+                // and new URLs can be added as they are discovered during
+                // processing.
+                Deque<URL> classPathUrlsToProcess = new LinkedList<>();
+                classPathUrlsToProcess.addAll(
+                        Arrays.asList(((URLClassLoader) classLoader).getURLs()));
+
+                if (JreCompat.isJre9Available()) {
+                    // The application and platform class loaders are not
+                    // instances of URLClassLoader. Use the class path in this
+                    // case.
+                    addClassPath(classPathUrlsToProcess);
+
+                    // TODO Java 9 module path
+                }
 
-            // 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);
+                while (!classPathUrlsToProcess.isEmpty()) {
+                    URL url = classPathUrlsToProcess.pop();
+
+                    if (processedURLs.contains(url)) {
+                        // Skip this URL it has already been processed
+                        continue;
                     }
 
-                    // Use a Deque so URLs can be removed as they are processed
-                    // and new URLs can be added as they are discovered during
-                    // processing.
-                    Deque<URL> classPathUrlsToProcess = new LinkedList<>();
-                    classPathUrlsToProcess.addAll(
-                            Arrays.asList(((URLClassLoader) classLoader).getURLs()));
-
-                    while (!classPathUrlsToProcess.isEmpty()) {
-                        URL url = classPathUrlsToProcess.pop();
-
-                        if (processedURLs.contains(url)) {
-                            // Skip this URL it has already been processed
-                            continue;
-                        }
+                    ClassPathEntry cpe = new ClassPathEntry(url);
 
-                        // TODO: Java 9 support. Details are TBD. It will depend
-                        //       on the extent to which Java 8 supports the
-                        //       Java 9 file formats since this code MUST run on
-                        //       Java 8.
-                        ClassPathEntry cpe = new ClassPathEntry(url);
-
-                        // 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()) &&
-                                        getJarScanFilter().check(scanType,
-                                                cpe.getName())) {
-                            if (log.isDebugEnabled()) {
-                                log.debug(sm.getString("jarScan.classloaderJarScan", url));
-                            }
-                            try {
-                                processedURLs.add(url);
-                                process(scanType, callback, url, null, isWebapp, classPathUrlsToProcess);
-                            } catch (IOException ioe) {
-                                log.warn(sm.getString("jarScan.classloaderFail", url), ioe);
-                            }
-                        } else {
-                            // JAR / directory has been skipped
-                            if (log.isTraceEnabled()) {
-                                log.trace(sm.getString("jarScan.classloaderJarNoScan", url));
-                            }
+                    // 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()) &&
+                                    getJarScanFilter().check(scanType,
+                                            cpe.getName())) {
+                        if (log.isDebugEnabled()) {
+                            log.debug(sm.getString("jarScan.classloaderJarScan", url));
+                        }
+                        try {
+                            processedURLs.add(url);
+                            process(scanType, callback, url, null, isWebapp, classPathUrlsToProcess);
+                        } catch (IOException ioe) {
+                            log.warn(sm.getString("jarScan.classloaderFail", url), ioe);
+                        }
+                    } else {
+                        // JAR / directory has been skipped
+                        if (log.isTraceEnabled()) {
+                            log.trace(sm.getString("jarScan.classloaderJarNoScan", url));
                         }
                     }
                 }
-                classLoader = classLoader.getParent();
+            }
+            classLoader = classLoader.getParent();
+        }
+    }
+
+
+    protected void addClassPath(Deque<URL> classPathUrlsToProcess) {
+        String classPath = System.getProperty("java.class.path");
+
+        if (classPath == null || classPath.length() == 0) {
+            return;
+        }
+
+        String[] classPathEntries = classPath.split(File.pathSeparator);
+        for (String classPathEntry : classPathEntries) {
+            File f = new File(classPath);
+            try {
+                classPathUrlsToProcess.add(f.toURI().toURL());
+            } catch (MalformedURLException e) {
+                log.warn(sm.getString("jarScan.classPath.badEntry", classPathEntry), e);
             }
         }
     }
@@ -326,7 +354,7 @@ public class StandardJarScanner implemen
      * Scan a URL for JARs with the optional extensions to look at all files
      * and all directories.
      */
-    private void process(JarScanType scanType, JarScannerCallback callback,
+    protected void process(JarScanType scanType, JarScannerCallback callback,
             URL url, String webappPath, boolean isWebapp, Deque<URL> classPathUrlsToProcess)
             throws IOException {
 



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