void (Path startDir, ClasspathCache.LoaderDataBuilder context, StrippedLongArrayList nameHashes) { // FileVisitor is not used to avoid getting file attributes for class files // (`.class` extension is a strong indicator that it is a file and not a directory) Deque<Path> dirCandidates = new ArrayDeque<>(); dirCandidates.add(startDir); Path dir; int rootDirAbsolutePathLength = startDir.toString().length(); while ((dir = dirCandidates.pollFirst()) != null) { try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir)) { boolean containsClasses = false; boolean containsResources = false; for (Path file : dirStream) { String path = getRelativeResourcePath(file.toString(), rootDirAbsolutePathLength); long nameHash = Xx3UnencodedString.hashUnencodedString(path); if (path.endsWith(ClasspathCache.CLASS_EXTENSION)) { nameHashes.add(nameHash); containsClasses = true; } else { nameHashes.add(nameHash); containsResources = true; if (!path.endsWith(".svg") && !path.endsWith(".png") && !path.endsWith(".xml")) { dirCandidates.addLast(file); } } } if (containsClasses || containsResources) { String relativeResourcePath = getRelativeResourcePath(dir.toString(), rootDirAbsolutePathLength); if (containsClasses) { context.addClassPackage(relativeResourcePath); } if (containsResources) { context.addResourcePackage(relativeResourcePath); } } } catch (NoSuchFileException | NotDirectoryException ignore) { } catch (IOException e) { //noinspection UseOfSystemOutOrSystemErr e.printStackTrace(System.err); } } }