Skip to content

Instantly share code, notes, and snippets.

@imwower
Created March 10, 2017 10:39
Show Gist options
  • Save imwower/0f250ee28114dd3a70c3f8a61e498c79 to your computer and use it in GitHub Desktop.
Save imwower/0f250ee28114dd3a70c3f8a61e498c79 to your computer and use it in GitHub Desktop.
java class finder with jar package
public class ClassFinder {
private static final char PKG_SEPARATOR = '.';
private static final char DIR_SEPARATOR = '/';
private static final String CLASS_FILE_SUFFIX = ".class";
private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?";
private static Logger logger = Logger.getLogger(ClassFinder.class);
/**
* scannedPackage: com.foo.bar
*
* @param scannedPackage
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static List<Class<?>> find(String scannedPackage) throws IOException, ClassNotFoundException {
List<Class<?>> classes = new ArrayList<Class<?>>();
String scannedPath = scannedPackage.replace(PKG_SEPARATOR, DIR_SEPARATOR);
logger.debug("scanned path : " + scannedPath);
URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath);
if (scannedUrl == null) {
throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage));
}
logger.debug("scanned url : " + scannedUrl);
if (scannedUrl.toString().startsWith("jar:")) { //jar
String fullPath = scannedUrl.getFile();
logger.debug("full path : " + fullPath);
String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", "");
logger.debug("jar path : " + jarPath);
JarFile jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
if (jarEntry == null) {
break;
}
if (jarEntry.getName().endsWith(".class")) {
String name = jarEntry.getName().replaceAll("/", "\\.").replace(".class","");
logger.debug("class name : " + name);
classes.add(Class.forName(name));
}
}
} else {
File scannedDir = new File(scannedUrl.getFile());
for (File file : scannedDir.listFiles()) {
classes.addAll(find(file, scannedPackage));
}
}
return classes;
}
private static List<Class<?>> find(File file, String scannedPackage) {
List<Class<?>> classes = new ArrayList<Class<?>>();
String resource = scannedPackage + PKG_SEPARATOR + file.getName();
if (file.isDirectory()) {
for (File child : file.listFiles()) {
classes.addAll(find(child, resource));
}
} else if (resource.endsWith(CLASS_FILE_SUFFIX)) {
int endIndex = resource.length() - CLASS_FILE_SUFFIX.length();
String className = resource.substring(0, endIndex);
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException ignore) {
}
}
return classes;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment