private static synchronized List<Class<?>> scanClasses(String packageName, String nameRegex, Predicate<Class<?>> filter, Class<? extends Annotation> annotated, ClassLoader classLoader) { packageName = U.or(packageName, ""); List<?> cacheKey = null; WebApp app = Ctxs.ctx().app(); Classes appClasses = app.getClasses(); Map<List<?>, List<Class<?>>> cache = appClasses.getCache(); cacheKey = U.list(packageName, nameRegex, filter, annotated, classLoader); List<Class<?>> cachedClasses = cache.get(cacheKey); if (cachedClasses != null) { return cachedClasses; } long startingAt = U.time(); Log.info("Filtering " + appClasses.size() + " classes", "annotated", annotated, "package", packageName, "name", nameRegex); Pattern regex = nameRegex != null ? Pattern.compile(nameRegex) : null; List<Class<?>> classes = filterClasses(appClasses, packageName, regex, filter, annotated); cache.put(cacheKey, classes); long timeMs = U.time() - startingAt; Log.info("Finished classpath scan", "time", timeMs + "ms", "classes", classes); return classes; }