Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting all Classes from a Package

Lets say I have a java package commands which contains classes that all inherit from ICommand can I get all of those classes somehow? I'm locking for something among the lines of:

Package p = Package.getPackage("commands");
Class<ICommand>[] c = p.getAllPackagedClasses(); //not real 

Is something like that possible?

like image 859
JustMaximumPower Avatar asked Nov 27 '09 20:11

JustMaximumPower


People also ask

How can you directly access all classes in the package in Java?

Since Java enforces the most restrictive access, we have to explicitly declare packages using the export or open module declaration to get reflective access to the classes inside the module.

How do I get all classes in a classpath?

You can get all classpath roots by passing an empty String into ClassLoader#getResources() . Enumeration<URL> roots = classLoader. getResources("");

How do I access classes from different packages?

To import java package into a class, we need to use java import keyword which is used to access package and its classes into the java program. Use import to access built-in and user-defined packages into your java source file so that your class can refer to a class that is in another package by directly using its name.

Can a package have multiple classes?

No, while defining multiple classes in a single Java file you need to make sure that only one class among them is public. If you have more than one public classes a single file a compile-time error will be generated.


2 Answers

Here's a basic example, assuming that classes are not JAR-packaged:

// Prepare.
String packageName = "com.example.commands";
List<Class<ICommand>> commands = new ArrayList<Class<ICommand>>();
URL root = Thread.currentThread().getContextClassLoader().getResource(packageName.replace(".", "/"));

// Filter .class files.
File[] files = new File(root.getFile()).listFiles(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        return name.endsWith(".class");
    }
});

// Find classes implementing ICommand.
for (File file : files) {
    String className = file.getName().replaceAll(".class$", "");
    Class<?> cls = Class.forName(packageName + "." + className);
    if (ICommand.class.isAssignableFrom(cls)) {
        commands.add((Class<ICommand>) cls);
    }
}
like image 50
BalusC Avatar answered Sep 25 '22 11:09

BalusC


Below, an implementation using the JSR-199 API i.e. classes from javax.tools.*:

List<Class> commands = new ArrayList<Class>();

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(
        null, null, null);

Location location = StandardLocation.CLASS_PATH;
String packageName = "commands";
Set<JavaFileObject.Kind> kinds = new HashSet<JavaFileObject.Kind>();
kinds.add(JavaFileObject.Kind.CLASS);
boolean recurse = false;

Iterable<JavaFileObject> list = fileManager.list(location, packageName,
        kinds, recurse);

for (JavaFileObject javaFileObject : list) {
    commands.add(javaFileObject.getClass());
}
like image 37
Pascal Thivent Avatar answered Sep 25 '22 11:09

Pascal Thivent