Find Java Classes Implementing an Interface

Find Java classes implementing an interface

Awhile ago, I put together a package for doing what you want, and more. (I needed it for a utility I was writing). It uses the ASM library. You can use reflection, but ASM turned out to perform better.

I put my package in an open source library I have on my web site. The library is here: http://software.clapper.org/javautil/. You want to start with the with ClassFinder class.

The utility I wrote it for is an RSS reader that I still use every day, so the code does tend to get exercised. I use ClassFinder to support a plug-in API in the RSS reader; on startup, it looks in a couple directory trees for jars and class files containing classes that implement a certain interface. It's a lot faster than you might expect.

The library is BSD-licensed, so you can safely bundle it with your code. Source is available.

If that's useful to you, help yourself.

Update: If you're using Scala, you might find this library to be more Scala-friendly.

Finding all classes implementing a specific interface

I had a similar need where I wanted to make sure that any classes created that implemented a certain interface were always truly serializable. I created a JavaClassFinder which walks through all directories in the classpath, and finds all classes assignable to the interface I cared about. Here is a code snippet:

public <T> List<Class<? extends T>> findAllMatchingTypes(Class<T> toFind) {
foundClasses = new ArrayList<Class<?>>();
List<Class<? extends T>> returnedClasses = new ArrayList<Class<? extends T>>();
this.toFind = toFind;
walkClassPath();
for (Class<?> clazz : foundClasses) {
returnedClasses.add((Class<? extends T>) clazz);
}
return returnedClasses;
}

I'm happy to share the code with you if it helps. The only draw back is that this will only handle .class files -- I didn't add the feature to unzip .jars and read class files from there. (But it wouldn't be a huge project to add that.)

UPDATE: I checked my source code for the above, and found it depends on a lot of helper classes in our standard utility library. To make it easier, I zipped up all the code needed, which you can download from JavaClassFinder.zip. This will set up directly in Eclipse, and you can take whatever portions of the code you need.

You will find a JUnit3 test in the project, called JavaClassFinderTest.java, which shows you the features and usage of the JavaClassFinder class. The only external dependency needed to run the Junit test is Junit.

Basic usage of this utility:

    JavaClassFinder classFinder = new JavaClassFinder();
List<Class<? extends MyTagInterface>> classes = classFinder.findAllMatchingTypes(MyTagInterface.class);

This will give you a List which contains any classes in the classpath which are assignable from the "MyTagInterface.class" (for example). Hope this helps.

How to check if an object implements an interface?

For an instance

Character.Gorgon gor = new Character.Gorgon();

Then do

gor instanceof Monster

For a Class instance do

Class<?> clazz = Character.Gorgon.class;
Monster.class.isAssignableFrom(clazz);

Determine if a Class implements a interface in Java

You should use isAssignableFrom:

if (YourInterface.class.isAssignableFrom(clazz)) {
...
}

How can I find all implementations of interface in classpath?

At best, this will be expensive. At worst (depending on the classloaders) it may be impossible.

I strongly suggest that you look for an alternative approach to the underlying problem that you are trying to address.

Is it possible to get all classes that implementing an interface?

There's no 100% reliable way to do what you want. The reason is because of how class loading works in Java.

Classes, in Java, are loaded "on demand". The first time a class is referenced in code (either statically or dynamically), the JVM will use the current class loader and try to load it. A ClassLoader has no method that gives all the classes that could be loaded from it, therefore you cannot iterate on classes.

There are some unreliable workarounds. For instance, if you know your ClassLoader will only ever load classes from inside a specific directory, or a specific JAR file, you can then use the classes related to your file system to find what ".class" files are available, then you can load everything (which takes time and will consume a lot of your PermGen, which might be a problem -- remember that you cannot easily unload a class! (unless you do some ClassLoader magic)), and use reflection to filter the classes implementing your interface.

The problem with this workaround is that it will most probably stop working if you ever change your deployment. For instance, if you start deploying a JAR file, then later on you decide to use a servlet container that will deal with WAR files, your code might not work anymore.

If you really want to try this approach, there's a project called Reflections that might be useful.

The most reliable way I've ever implemented this is by using an Annotation Processor. You write an annotation, you annotate your interface, and you write some code that will get executed by the compiler, in compile-time, that will collect the classes implementing your interface and save their names in a resource file. Then you write a class with a method that reads that file and gives you a Class object for each class name listed in that resource file.

The problem with this approach is that only classes that are compiled in my build process will get listed (ie, if you publish a library with an interface and expect others to implement your interface, this approach won't be useful, since your code will never know about the class in others' projects). If this is enough for you, as it was for me, this solution works flawlessly. I can use it in Servlet Containers with WAR (exploded or not) deployments, in executable jars, whatever. It will always work.

How can I get the implementation class name based on the interface object in Java

Just use object.getClass() - it will return the runtime class used implementing your interface:

public class Test {

public interface MyInterface { }
static class AClass implements MyInterface { }

public static void main(String[] args) {
MyInterface object = new AClass();
System.out.println(object.getClass());
}
}

List of Classes implementing an Interface

List<Class<? implements MyInterface>> ClassList = new ArrayList<Class<? implements MyInterface>>(); 

should be

List<Class<? extends MyInterface>> ClassList = new ArrayList<Class<? extends MyInterface>>(); 

there is no implements keyword in the world of generics. if you want a type parameter that implements an interface , use the extends keyword to represent it.



Related Topics



Leave a reply



Submit