How can you find all classes that implements your interface ?

T

tomjbr.56770318

I would like to figure out how you can implement a method like this,
which should locate all classes that are available at the classpath
that implements a certain interface:
'public Class[] getImplementingClasses(Class someInterface)'
or even better:
'public Class[] getSubtypes(Class someBaseType)'
(where basetype can be either an interface or a baseclass, while each
returned subtype can be either a subclass or subinterface)

When I was googling, I found 'Commons Discovery' at
http://commons.apache.org/discovery/
The homepage there is claiming that:
"Fundamentally, Discovery locates classes that implement a given Java
interface."

So, this seemed to be what I was looking for.
However, I can not figure out or see any example about how I actually
can retrieve a list of the classes that implement a given interface...

Can someone please provide a code example, either by using Commons
Discovery, or some other open source component (or maybe it is even
fairly simple with the Java Core library ?)

/ Tom
 
J

Joshua Cranmer

I would like to figure out how you can implement a method like this,
which should locate all classes that are available at the classpath
that implements a certain interface:

The extremely short answer: this is impossible in the general case.

Long answer:

Java's class loading mechanism makes ultimately discovering all
implementing classes impossible. That said, it is possible to
approximate the feature by manually parsing the classpaths and peeking
inside the jars to find the classes to see which implement an interface.

However, the more important information is, "What is the context?" Java
6 defines a ServiceProvider interface that allows a JAR file to declare
that it provides some service implementations.
 
T

tomjbr.56770318

Java's class loading mechanism makes ultimately discovering all
implementing classes impossible. That said, it is possible to
approximate the feature by manually parsing the classpaths and peeking
inside the jars to find the classes to see which implement an interface.

Hmm, I do not understand why this would be only an approximation of
the feature.
Is it not possible to iterate all classes that are available at the
classpath and see if they implement an interface ?
If it is, then I do not see how you might risk to not find an
implementing class ?

Does anyone have a link to a code example illustrating how to do this
(unless there is no component that has a simple API, similar to the
method I suggested in my question) ?

Would it help, if I would use a restriction of putting all the
implementations in one given package ?
In other words, would this kind method be easier to implement:
'public Class[] getImplementingClasses(Package
packageWithTheImplementations, Class someInterface)'

My purpose is that I want to autodetect implementations of a
interface.
In other words, I would like to avoid having to define (for each
implementing class) strings in a configuration, that would be used
like this:
MyInterface myObject =
(MyInterface)Class.forName(stringWithClassNameRetrievedFromConfigurationFile).newInstance();

/ Tom
 
M

Matt Humphrey

Hmm, I do not understand why this would be only an approximation of
the feature.
Is it not possible to iterate all classes that are available at the
classpath and see if they implement an interface ?
If it is, then I do not see how you might risk to not find an
implementing class ?

The classloader simply provides the class given its name--it has no "get all
classes". In the general case it has to work with classes that are
implemented dynamically or pulled over a network. Only things like jars or
files have a meaningful sense of iterating through all class names.
Does anyone have a link to a code example illustrating how to do this
(unless there is no component that has a simple API, similar to the
method I suggested in my question) ?

Would it help, if I would use a restriction of putting all the
implementations in one given package ?
In other words, would this kind method be easier to implement:
'public Class[] getImplementingClasses(Package
packageWithTheImplementations, Class someInterface)'

Package isn't synonymous with jar or location. The same package can appear
in any location.

To make this work you have to know that the classes you want are in some
kind of container (jar, etc) that you can independently iterate through,
hence the emphasis on looking at the classpath and in jars.

Matt Humphrey http://www.iviz.com/
 
R

Roger Lindsjö

Hmm, I do not understand why this would be only an approximation of
the feature.
Is it not possible to iterate all classes that are available at the
classpath and see if they implement an interface ?
If it is, then I do not see how you might risk to not find an
implementing class ?

No, the class loaders might not only load claases from the classpath,
but they might be loaded remotely or even be generated on the fly.

I have worked on systems where a simple bootstrap with a url as input
would load a full servlet container from a main server. Deploying on a
new machine meant just copying a small jar file onto it and the do a
java -jar mainserver.address:port.
Does anyone have a link to a code example illustrating how to do this
(unless there is no component that has a simple API, similar to the
method I suggested in my question) ?

Would it help, if I would use a restriction of putting all the
implementations in one given package ?
In other words, would this kind method be easier to implement:
'public Class[] getImplementingClasses(Package
packageWithTheImplementations, Class someInterface)'

My purpose is that I want to autodetect implementations of a
interface.
In other words, I would like to avoid having to define (for each
implementing class) strings in a configuration, that would be used
like this:
MyInterface myObject =
(MyInterface)Class.forName(stringWithClassNameRetrievedFromConfigurationFile).newInstance();

/ Tom

//Roger Lindsjö
 
P

Patricia Shanahan

Would it help, if I would use a restriction of putting all the
implementations in one given package ?
....

How about limiting it to a single directory, and specifying that the
class must already exist at the time the program starts? That way, you
could just search the directory for .class files, and examine any you
find to see if they contain a class that implements your interface.

Patricia
 
S

Stefan Ram

How can you find all classes that implements your interface ?

I have written a library routine for this, based on code by
Ralf Ullrich.

For example, to find all classes implementing »java.util.Map«,
one sets a filter accepting only classes which
»java.util.Map« is assignable from:

public boolean accepts( final java.lang.Class class_ )
{ return java.util.Map.class.isAssignableFrom( class_ ); }

One also needs to provide a starting class to find the jar, which
is done as follows.

public java.lang.String entryPath(){ return "java.lang.Object"; }

The jar containing this type will be chosen for exploration.

In the following example, the client does not need to specify
this »entryPath«, because "java.lang.Object" already is the
default class. These defaults are being inherited from
»de.dclj.ram.java.lang.reflect.Finder.DefaultSpecification«.

The example client is:

public class Main
{ /* based on an idea and on code by Ralf Ullrich from 2006 */

public static void main( final java.lang.String[] args )
{ new de.dclj.ram.java.lang.reflect.Finder
( new de.dclj.ram.java.lang.reflect.Finder.DefaultSpecification()
{
public boolean isClassFinder(){ return true; }

public boolean accepts( final java.lang.Class class_ )
{ return java.util.Map.class.isAssignableFrom( class_ ); }

}).inspectJar(); }}

class java.lang.ProcessEnvironment
class java.rmi.server.RemoteObjectInvocationHandler$MethodToHash_Maps$1
class java.security.AuthProvider
(...)
class java.util.Properties
class java.util.Hashtable
interface java.util.Map

The library »ram.jar« is an early GPL publication in alpha state,
it is experimental, changing, and mostly undocumented. See:

http://www.purl.org/stefan_ram/pub/ram-jar

Known issues:

- I have ideas to improve the interface, which are not yet
implemented.

- To compile the library from the sources, one might need
to take care of some minor bugs: If I remember
correctly, some »private«s need to be replaced by »public«,
as indicated by compiler error messages.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top