Skip to content

Instantly share code, notes, and snippets.

@aleskiontherun
Last active December 23, 2019 09:59
Show Gist options
  • Save aleskiontherun/096a60f94ae969d2ccbb9a7c706ed0e3 to your computer and use it in GitHub Desktop.
Save aleskiontherun/096a60f94ae969d2ccbb9a7c706ed0e3 to your computer and use it in GitHub Desktop.
Find groovy classes in a package and all its subpackages. Scans the package directory and subdirectories. Works when running from a jar or the filesystem.
class ClassFinder {
static List<Class> findClasses(Class clazz) {
URL srcLocation = clazz.getProtectionDomain().getCodeSource().getLocation()
String packageName = clazz.package.name
List<String> classNames
if (srcLocation.toString().endsWith('.jar')) {
String packagePath = packageName.replaceAll(/\./, '/')
classNames = loadClassNamesFromJar(srcLocation, packagePath)
} else {
File dir = new File(clazz.getResource('').toURI())
classNames = loadClassNamesFromDir(dir, packageName)
}
return classNames.collect { Class.forName(it) }
}
private static List<String> loadClassNamesFromJar(URL jarLocation, String packagePath) {
ZipInputStream zip = new ZipInputStream(jarLocation.openStream());
ZipEntry e
List<String> classNames = []
while (e = zip.getNextEntry()) {
String name = e.getName()
if (name.matches(/$packagePath\/[^\$]+\.class/)) {
classNames.add(name.split(/\./).first().replaceAll(/\//, '.'))
}
}
return classNames
}
private static List<String> loadClassNamesFromDir(File dir, String packageName) {
List<String> classNames = []
dir.listFiles().toList().each { file ->
if (file.isDirectory()) {
assert !file.getName().contains(".")
classNames.addAll(loadClassNamesFromDir(file, packageName + '.' + file.name))
} else if (file.getName().endsWith(".groovy")) {
classNames.add(packageName + '.' + file.getName().split(/\./).toList().first());
}
}
return classNames
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment