You can't browse a directory on the classpath recursively.
See this post: How to use ClassLoader.getResources() correctly?
If you know you're looking at a JAR file however, you might open it directly as an archive and browse the files.
Somebody came up with a useful answer for this question: Get all of the Classes in the Classpath
You could adapt this code to browse through all JAR files and directories on your classpath and apply some filter for your directory name yourself. The example will list all classes from the gnu.trove.* package:
import java.io.File;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class Test
{
public static void main(String[] args)
{
final String dirname = "gnu.trove.";
findClasses(new Visitor<String>() {
@Override
public boolean visit(String classname)
{
if (classname.startsWith(dirname)) {
System.out.println(classname);
}
return true;
}
});
}
public interface Visitor<T>
{
public boolean visit(T t);
}
public static void findClasses(Visitor<String> visitor)
{
String classpath = System.getProperty("java.class.path");
String[] paths = classpath.split(System.getProperty("path.separator"));
String javaHome = System.getProperty("java.home");
File file = new File(javaHome + File.separator + "lib");
if (file.exists()) {
findClasses(file, file, true, visitor);
}
for (String path : paths) {
file = new File(path);
if (file.exists()) {
findClasses(file, file, true, visitor);
}
}
}
private static boolean findClasses(File root, File file,
boolean includeJars, Visitor<String> visitor)
{
if (file.isDirectory()) {
for (File child : file.listFiles()) {
if (!findClasses(root, child, includeJars, visitor)) {
return false;
}
}
} else {
if (file.getName().toLowerCase().endsWith(".jar") && includeJars) {
JarFile jar = null;
try {
jar = new JarFile(file);
} catch (Exception ex) {
}
if (jar != null) {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
int extIndex = name.lastIndexOf(".class");
if (extIndex > 0) {
if (!visitor.visit(name.substring(0, extIndex)
.replace("/", "."))) {
return false;
}
}
}
}
} else if (file.getName().toLowerCase().endsWith(".class")) {
if (!visitor.visit(createClassName(root, file))) {
return false;
}
}
}
return true;
}
private static String createClassName(File root, File file)
{
StringBuffer sb = new StringBuffer();
String fileName = file.getName();
sb.append(fileName.substring(0, fileName.lastIndexOf(".class")));
file = file.getParentFile();
while (file != null && !file.equals(root)) {
sb.insert(0, '.').insert(0, file.getName());
file = file.getParentFile();
}
return sb.toString();
}
}
Here is some code for ignoring JAR files and just going through the files on directories on your classpath:
import java.io.File;
public class Test
{
public static void main(String[] args)
{
findClasses(new Visitor<String>() {
@Override
public boolean visit(String classname)
{
// apply your filtering here
System.out.println(classname);
return true;
}
});
}
public interface Visitor<T>
{
public boolean visit(T t);
}
public static void findClasses(Visitor<String> visitor)
{
String classpath = System.getProperty("java.class.path");
String[] paths = classpath.split(System.getProperty("path.separator"));
for (String path : paths) {
File file = new File(path);
// Ignore JAR files, just go through directories on the classpath
if (file.isFile()) {
continue;
}
findFiles(file, file, visitor);
}
}
private static boolean findFiles(File root, File file,
Visitor<String> visitor)
{
if (file.isDirectory()) {
for (File child : file.listFiles()) {
if (!findFiles(root, child, visitor)) {
return false;
}
}
} else {
if (!visitor.visit(createRelativePath(root, file))) {
return false;
}
}
return true;
}
private static String createRelativePath(File root, File file)
{
StringBuffer sb = new StringBuffer();
sb.append(file.getName());
file = file.getParentFile();
while (file != null && !file.equals(root)) {
sb.insert(0, '/').insert(0, file.getName());
file = file.getParentFile();
}
return sb.toString();
}
}