String[] (String packageName, @Nullable Path rootPath, JavaTestConfigurationBase configuration, Function<? super ClassLoader, ? extends Predicate<Class<?>>> predicateProducer) { ClassLoader classLoader = createUsersClassLoader(configuration); Set<String> classes = new HashSet<>(); try { String packagePath = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(packagePath); Predicate<Class<?>> classPredicate = predicateProducer.apply(classLoader); while (resources.hasMoreElements()) { URL url = resources.nextElement(); //don't search for tests in jars if ("jar".equals(url.getProtocol())) continue; Path baseDir = Paths.get(url.toURI()); //collect tests under single module test output only if (rootPath != null && !baseDir.startsWith(rootPath)) continue; String pathSeparator = baseDir.getFileSystem().getSeparator(); Files.walkFileTree(baseDir, new SimpleFileVisitor<>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { ProgressManager.checkCanceled(); FileVisitResult result = super.visitFile(file, attrs); File f = file.toFile(); String fName = f.getName(); if (fName.endsWith(".class")) { try { Path relativePath = baseDir.relativize(file.getParent()); String subpackageName = StringUtil.getQualifiedName(relativePath.toString().replace(pathSeparator, "."), FileUtilRt.getNameWithoutExtension(fName)); String fqName = StringUtil.getQualifiedName(packageName, subpackageName); Class<?> aClass = Class.forName(fqName, false, classLoader); //is potential junit 4 int modifiers = aClass.getModifiers(); if (Modifier.isAbstract(modifiers) || !Modifier.isPublic(modifiers) || aClass.isMemberClass() && !Modifier.isStatic(modifiers)) { return result; } if (classPredicate.test(aClass)) { classes.add(fqName); } } catch (Throwable e) { LOG.info("error processing: " + fName + " of " + baseDir, e); } } return result; } }); } } catch (ProcessCanceledException e) { throw e; } catch (Throwable e) { LOG.error(e); } return ArrayUtilRt.toStringArray(classes); }