final RelativePathToElementMap classpathElementMap = new RelativePathToElementMap( enableRecursiveScanning, scanSpec, nestedJarHandler, interruptionChecker); WorkQueue.runWorkQueue(rawClasspathEltOrder, executorService, numParallelTasks,
/** * Recursively perform a depth-first search of jar interdependencies, breaking cycles if necessary, to determine * the final classpath element order. */ private static void findClasspathOrder(final ClasspathElement currSingleton, final RelativePathToElementMap classpathElementMap, final HashSet<ClasspathElement> visitedClasspathElts, final ArrayList<ClasspathElement> order) throws InterruptedException { if (visitedClasspathElts.add(currSingleton)) { if (!currSingleton.skipClasspathElement) { // Don't add a classpath element, if it is marked to be skipped. order.add(currSingleton); } // Whether or not a classpath element should be skipped, add any child classpath elements that are // not marked to be skipped (i.e. keep recursing) if (currSingleton.childClasspathElts != null) { for (final RelativePath childClasspathElt : currSingleton.childClasspathElts) { final ClasspathElement childSingleton = classpathElementMap.get(childClasspathElt); if (childSingleton != null) { findClasspathOrder(childSingleton, classpathElementMap, visitedClasspathElts, order); } } } } }
if (classpathElementMap.get(rawClasspathEltPath) != null) { if (preScanLog != null) { preScanLog.log("Ignoring duplicate classpath element: " + rawClasspathEltPath); if (isModule) { classpathElementMap.createSingleton(rawClasspathEltPath, preScanLog); } else if (isFile && !scanSpec.scanJars) { if (preScanLog != null) { classpathElementMap.createSingleton(rawClasspathEltPath, preScanLog);
/** * Recursively perform a depth-first search of jar interdependencies, breaking cycles if necessary, to determine * the final classpath element order. */ private static List<ClasspathElement> findClasspathOrder(final List<RelativePath> rawClasspathElements, final RelativePathToElementMap classpathElementMap) throws InterruptedException { // Recurse from toplevel classpath elements to determine a total ordering of classpath elements (jars with // Class-Path entries in their manifest file should have those child resources included in-place in the // classpath). final HashSet<ClasspathElement> visitedClasspathElts = new HashSet<>(); final ArrayList<ClasspathElement> order = new ArrayList<>(); for (final RelativePath toplevelClasspathElt : rawClasspathElements) { final ClasspathElement toplevelSingleton = classpathElementMap.get(toplevelClasspathElt); if (toplevelSingleton != null) { findClasspathOrder(toplevelSingleton, classpathElementMap, visitedClasspathElts, order); } } return order; }
@Override public void processWorkQueueRef(final WorkQueue<RelativePath> workQueue) { // Store a ref back to the work queue in the classpath element map, because some // classpath elements will need to schedule additional classpath elements for scanning, // e.g. "Class-Path:" refs in jar manifest files classpathElementMap.setWorkQueue(workQueue); } }, interruptionChecker, preScanLog);
/** Close the classpath elements. */ @Override public void close() throws Exception { for (final ClasspathElement classpathElt : values()) { classpathElt.close(); } } }