Skip to content

Instantly share code, notes, and snippets.

@ChinaXing
Last active August 29, 2015 14:14
Show Gist options
  • Save ChinaXing/2b61c1b731191b91051a to your computer and use it in GitHub Desktop.
Save ChinaXing/2b61c1b731191b91051a to your computer and use it in GitHub Desktop.
scan classes in a package, and load them to a list
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ClassScanner{
public static <T> List<Class<? extends T>> listPackageClass(String pkgName, Class<T> superClass) {
List<Class<? extends T>> result = new ArrayList<Class<? extends T>>();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
Enumeration<URL> resources = classLoader.getResources(pkgName.replace(".", "/"));
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
if (resource.getProtocol().equalsIgnoreCase("jar")) {
JarURLConnection urlConnection = (JarURLConnection) resource.openConnection();
JarFile jarFile = urlConnection.getJarFile();
String prefix = urlConnection.getEntryName();
Enumeration<JarEntry> entryEnumeration = jarFile.entries();
while (entryEnumeration.hasMoreElements()) {
JarEntry entry = entryEnumeration.nextElement();
if (entry.isDirectory()) continue;
if (!entry.getName().startsWith(prefix)) continue;
if (entry.getName().endsWith(".class")) {
String className = entry.getName().substring(0, entry.getName().length() - 6).replace("/", ".");
loadClass(className, result, superClass);
}
}
continue;
}
File f = new File(resource.getFile());
if (!f.isDirectory()) { // should not be file , but a directory
continue;
}
String[] files = f.list(new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
return s.endsWith(".class");
}
});
for (String classFileName : files) {
String className = classFileName.substring(0, classFileName.length() - 6);
loadClass(pkgName + "." + className, result);
}
}
} catch (Throwable t) {
t.printStackTrace();
}
return result;
}
private static <T> void loadClass(String className, List<Class<? extends T>> result, Class<T> superClass) {
try {
Class c = Class.forName(className);
if (superClass.isAssignableFrom(c)
&& !Modifier.isInterface(c.getModifiers())
&& !Modifier.isAbstract(c.getModifiers())) {
result.add(c);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment