Searching for Java class in a package recursively by name

Is there some easy, well-explored way to search for a given class by name in a package, and, recursively, in all sub-packages of a this package?

I.e. given existing classes, such as:

  • foo.MyClass
  • foo.bar.baz.some.more.MyClass
  • foo.bar.baz.some.more.OtherClass

I’d like to run something like magicMethod("foo.bar.baz", "MyClass") and get Class foo.bar.baz.some.more.MyClass as result.

Obviously, it’s fairly easy to implement manually – by exploring loaded packages from Package.getPackages(), filtering whatever’s appropriate and seeking for the class in a loop using Class.forName(...) – but may be there’s something in standard Java libraries or some other widespread libraries, such as Apache Commons, that solve this task?

Answer

Shameless plug for my own OSS software : https://bitbucket.org/stevevls/metapossum-scanner/wiki, available in maven central.

The typical use cases for this library are for doing things like looking for implementing classes like this:

Set<Class<? extends MyDiscoverableHelper>> implementingClasses = new ClassesInPackageScanner()
    .findImplementers("com.mypackage.service.impl", MyDiscoverableHelper.class);

or annotated class like this:

Set<Class> entityClasses = new ClassesInPackageScanner()
    .findAnnotatedClasses("com.mypackage.datamodel", javax.persistence.Entity.class);

but the selection strategy can be swapped out by implementing an interface and passing it to the scanner. If what you’re trying to do is find classes by name, the code snippet would look like this:

Set<Class> entityClasses = new ClassesInPackageScanner().setResourceNameFilter(new ResourceNameFilter() {
    public boolean acceptResourceName(java.lang.String packageName, java.lang.String fileName) {
        return fileName.equals("MyClass.class");
    }
}).scan("foo");

I wrote this library a while ago because I never found an implementation that I liked for exploring packages. There are a number of libraries that have their own internal API, but nothing that I knew of that packaged it up in a nice API.

Plus, exploring the Package(s) is actually tricky to get right. It’s not as straightforward as it may seem at first!

Leave a Reply

Your email address will not be published. Required fields are marked *