我曾经启动了一个项目,通过使用 null、0、1、-1、@987654326 等狡猾的参数反射性地调用构造函数和方法来自动测试在类路径上找到的类是否存在运行时异常@等
该项目有一个名为 Finder 的类,可以大致满足您的需求:
static List<Class<?>> findClassesForPackage(String packagename, Report report) throws ClassNotFoundException {
// 'classes' will hold a list of directories matching the package name.
// There may be more than one if a package is split over multiple
// jars/paths
List<Class<?>> classes = new ArrayList<Class<?>>();
List<File> directories = new ArrayList<File>();
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
throw new ClassNotFoundException("Can't get class loader.");
}
// Ask for all resources for the path
String path = packagename.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
while (resources.hasMoreElements()) {
URL res = resources.nextElement();
if (res.getProtocol().equalsIgnoreCase("jar")) {
JarURLConnection conn = (JarURLConnection) res.openConnection();
JarFile jar = conn.getJarFile();
for (JarEntry entry : Collections.list(jar.entries())) {
if (entry.getName().startsWith(path) && entry.getName().endsWith(".class")
&& !entry.getName().contains("$")) {
String className = entry.getName().replace("/", ".").substring(0,
entry.getName().length() - 6);
LOG.debug("Adding JAR className " + className);
try {
Class<?> clazz = Class.forName(className);
classes.add(clazz);
report.addClass(className);
} catch (Throwable throwable) {
ParamSet params = new ParamSet();
params.addParamValue(new ParamValue(className, "fully qualified classname"));
report.addError(className, new Error("Class.forName()", params, throwable));
}
}
}
} else
directories.add(new File(URLDecoder.decode(res.getPath(), "UTF-8")));
}
} catch (NullPointerException e) {
throw new ClassNotFoundException(String.format("%s does not appear to be a valid package", packagename), e);
} catch (UnsupportedEncodingException e) {
throw new ClassNotFoundException(String.format("%s does not appear to be a valid package", packagename), e);
} catch (IOException e) {
throw new ClassNotFoundException(String.format("Could not get all resources for %s", packagename), e);
}
List<String> subPackages = new ArrayList<String>();
// For every directory identified capture all the .class files
for (File directory : directories) {
if (directory.exists()) {
// Get the list of the files contained in the package
File[] files = directory.listFiles();
for (File file : files) {
// add .class files to results
String fileName = file.getName();
if (file.isFile() && fileName.endsWith(".class")) {
// removes the .class extension
String className = packagename + '.' + fileName.substring(0, fileName.length() - 6);
LOG.debug("Adding FILE className " + className);
try {
Class<?> clazz = Class.forName(className);
classes.add(clazz);
report.addClass(className);
} catch (Throwable throwable) {
ParamSet params = new ParamSet();
params.addParamValue(new ParamValue(className, "fully qualified classname"));
report.addError(className, new Error("Class.forName()", params, throwable));
}
}
// keep track of subdirectories
if (file.isDirectory()) {
subPackages.add(packagename + "." + fileName);
}
}
} else {
throw new ClassNotFoundException(String.format("%s (%s) does not appear to be a valid package",
packagename, directory.getPath()));
}
}
// check all potential subpackages
for (String subPackage : subPackages) {
classes.addAll(findClassesForPackage(subPackage, report));
}
return classes;
}
您可能必须剥离一些用于报告等的代码。