Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2006

Tip: Looking for answers? Try searching our database.

Reflection: discovering the implementations of an interface

Thread view: 
z-man - 10 Oct 2006 07:47 GMT
Hello

What's the smoother way to discover via reflection all the classes
implementing a specific interface inside a package?

Example:

package com.acme.mypackage
{
MyInterface.class
Class1.class implements MyInterface
Class2.class
Class3.class
Class4.class implements MyInterface
Class5.class implements MyInterface
}

I want to retrieve Class1, Class4 and Class5.

Many thanks.
Thomas Weidenfeller - 10 Oct 2006 07:58 GMT
> What's the smoother way to discover via reflection all the classes
> implementing a specific interface inside a package?

This has been discussed a thousand times here. There is no general solution.

Please read an archive of this group.

/Thomas
Signature

The comp.lang.java.gui FAQ:
http://gd.tuwien.ac.at/faqs/faqs-hierarchy/comp/comp.lang.java.gui/
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq

Andrew Thompson - 10 Oct 2006 08:06 GMT
....
> What's the smoother way to discover via reflection ...

'hackich' or 'second hand' or 'cobbled together' are words
or phrases I might expect to hear in sentences that also
have the word 'reflection' in them - 'smoother' came as quite
a shock!

(and I see Thomas has already addressed the technical
points, so I won't revisit them..)

Andrew T.
z-man - 10 Oct 2006 08:49 GMT
> ....
>> What's the smoother way to discover via reflection ...
[quoted text clipped - 3 lines]
> have the word 'reflection' in them - 'smoother' came as quite
> a shock!

???

I can't grasp the tone of what you're saying, Andrew...

I think that Java core reflection implementation is quite incomplete;
otherwise, there wouldn't have been so many requests of such a
functionality over time (as Thomas says: "This has been discussed a
THOUSAND times here. There is no general solution.").

Using Mono, I found that .NET reflection implementation is much more
consistent and... smoother (are you shocked?).

Why hasn't Sun addressed this need till now?

Would it be so hard to release an official reflection class that
transparently discovers all the *available* classes from a specific package?
Chris Uppal - 10 Oct 2006 09:50 GMT
> Would it be so hard to release an official reflection class that
> transparently discovers all the *available* classes from a specific
> package?

You concept of "package" is at fault.  That's to say: you have a mental
"picture" of what they are and how they work which is only approximately
connected with reality.

I could trivially create a "package" which generated random new classes every
10 seconds for as long as the application is running.  I could trivially create
a classloader which /always/ found a class for any possible classname it was
asked for -- again generating classes on the fly (and probably randomly).  In
either case your question has no meaning at all.

If you want to restrict yourself to less dynamic ideas of what a package is,
and what sorts of classloader you are going to use, then the question may
become feasible to answer -- for instance, you could simply include a list of
classes (maybe indexed by interfaces) as a readable text resource in the same
JAR.  Alternatively, you could discover the location from which the classloader
was loading .class files (if there was any concept of "location") and use
location-specific code to discover what .class files are available there.  E.g.
reading the table-of-contents of a JAR file considered as a ZIP file, or
listing (recursively) the contents of a directory.  Note that this may not be
possible; for instance if the "location" is an HTTP base-URL.

   -- chris
z-man - 10 Oct 2006 11:06 GMT
>> Would it be so hard to release an official reflection class that
>> transparently discovers all the *available* classes from a specific
[quoted text clipped - 9 lines]
> asked for -- again generating classes on the fly (and probably randomly).  In
> either case your question has no meaning at all.

Why? As the JVM loads such dynamic classes, couldn't it keep track of
their in-memory presence for on-the-fly reflection-at-package-level
purposes?

As I said, I intended to discover "all the *available* classes from a
specific package": AVAILABLE doesn't mean POSSIBLE. It's self-evident
that I didn't want to discover the whole universe of the possible
imaginative package: I simply did NOT want that. I wanted all the
reachable classes from a specific package within the classpath scope: is
it SO insane?

In fact, as the context of my question should have implied, I was
referring to the most common, real-life case: non-dynamically-generated
classes. *Possible* doesn't mean *practical*: I think that the typical
scenario is NOT randomly-generated classes, but well-established,
non-volatile classes.

> If you want to restrict yourself to less dynamic ideas of what a package is,

YOU are restricting yourself to the limits of a platform.

> and what sorts of classloader you are going to use, then the question may
> become feasible to answer -- for instance, you could simply include a list of
> classes (maybe indexed by interfaces) as a readable text resource in the same
> JAR.

Awkward.

> Alternatively, you could discover the location from which the classloader
> was loading .class files (if there was any concept of "location") and use
> location-specific code to discover what .class files are available there.  E.g.
> reading the table-of-contents of a JAR file considered as a ZIP file, or
> listing (recursively) the contents of a directory.  Note that this may not be
> possible; for instance if the "location" is an HTTP base-URL.

OK.

As many people have asked for such a functionality, maybe just ignoring
the problem (as no official practise seems to exist) is somewhat an
exercise for snob theorists. ;-)
Lothar Kimmeringer - 10 Oct 2006 19:58 GMT
> As many people have asked for such a functionality, maybe just ignoring
> the problem (as no official practise seems to exist) is somewhat an
> exercise for snob theorists. ;-)

Fot this the most easy way is to implement your own ClassLoader
that is used at the beginning of your application that is
collecting this kind of information within a map you can access
without the need of Reflection (at the point of time you need it).
Of course this adds more overhead to the loading of classes, but
that's something you have to accept in your special case. No
need to slow down all the other applications (I assume about
99.999%) that doesn't.

Easy (just a method-call), smooth (fast, reliable) and also
cool (adding ClassLoaders) with so little effort. SUN thought
of everything ;-)

Your attempt of using Reflection for this kind of thing is
simply the wrong one, so there is no need to start a discussion,
why something like Mono (AKA .NET) or any other system that
has been created many years after Java, has got some specific
feature, Java doesn't.

Regards, Lothar
Signature

Lothar Kimmeringer                E-Mail: spamfang@kimmeringer.de
              PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
                questions!

Chris Uppal - 11 Oct 2006 10:16 GMT
> Why? As the JVM loads such dynamic classes, couldn't it keep track of
> their in-memory presence for on-the-fly reflection-at-package-level
> purposes?

Of course it could.  It does so internally.  But why /should/ it ?  All that
would happen is that people would misuse it[*]: the collection of classes which
/have/ been loaded is not the same as the collection of classes which are
/available/ to be loaded (even in a completely static situation).

If you need that functionality (but what for ??) then it's simple to add it.
If you need to be able to ask what classes /could/ be loaded then there is no
general solution -- so you should expect to be forced to create special-purpose
code to handle your own specific situation, taking advantage of whatever
situation-specific factors you can.

   -- chris

([*] Maybe /you/ wouldn't misuse it, but the majority of the people who ask
this, or closely related questions, here would)
opalpa opalpa@gmail.com http://opalpa.info - 10 Oct 2006 09:07 GMT
http://forum.java.sun.com/thread.jspa?threadID=341935&start=15

Note that list of classes implementing an interface can change while
program is executing.

opalpa
opalpa@gmail.com
http://opalpa.info/
z-man - 10 Oct 2006 10:01 GMT
> http://forum.java.sun.com/thread.jspa?threadID=341935&start=15

Great! That was the missing point.

> Note that list of classes implementing an interface can change while
> program is executing.

OK, my scenario is not so dynamic anyway.

Many thanks, opalpa!
Lothar Kimmeringer - 10 Oct 2006 20:02 GMT
> http://forum.java.sun.com/thread.jspa?threadID=341935&start=15
>
> Note that list of classes implementing an interface can change while
> program is executing.

Note also, that Class.forName calls cinit.

Regards, Lothar
Signature

Lothar Kimmeringer                E-Mail: spamfang@kimmeringer.de
              PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
                questions!

Piotr Kobzda - 10 Oct 2006 20:37 GMT
> Note also, that Class.forName calls cinit.

Class.forName(name, false, null) won't do that.

piotr
Piotr Kobzda - 10 Oct 2006 13:19 GMT
> What's the smoother way to discover via reflection all the classes
> implementing a specific interface inside a package?

Not necessarily smoother but possibly most accurate way to achieve that
is to instrument your program with you own agent (see
java.lang.instrument package specifications on how to do that), and than
having Instrumentation instance (passed to the agent's premain() by the
JVM) filter the results of getAllLoadedClasses() call on that instance.

piotr
z-man - 10 Oct 2006 13:40 GMT
>> What's the smoother way to discover via reflection all the classes
>> implementing a specific interface inside a package?
[quoted text clipped - 4 lines]
> having Instrumentation instance (passed to the agent's premain() by the
> JVM) filter the results of getAllLoadedClasses() call on that instance.

Really interesting.

This way it should be possible to retrieve dynamically-generated classes
too, shouldn't it?

Many thanks, Piotr!
Piotr Kobzda - 10 Oct 2006 20:34 GMT
> This way it should be possible to retrieve dynamically-generated classes
> too, shouldn't it?

Of course, it should.

See the output of running the following agent:

import java.lang.instrument.Instrumentation;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * After building agent's jar with duly manifest run it with:
 *   java -javaagent:agent.jar ClassesAgent
 *
 * @author pk
 */
public class ClassesAgent {

    private static Instrumentation inst;

    public static void premain(String agentArgs, Instrumentation inst) {
        ClassesAgent.inst = inst;
    }

    public static Class[] getAllClassesAssignableFrom(Class...
interfaces) {
        ArrayList<Class> found = new ArrayList<Class>();
        loop: for (Class c : inst.getAllLoadedClasses()) {
            for (Class<?> ic : interfaces)
                if (!ic.isAssignableFrom(c))
                    continue loop;
            found.add(c);
        }
        return found.toArray(new Class[found.size()]);
    }

    interface Test {}

    public static void main(String[] args) throws Exception {
        System.out.println("lookup of classes implementing " +
Test.class + "...");
        Class[] classes;
        classes = getAllClassesAssignableFrom(Test.class);
        System.out.println("classes found: " + Arrays.toString(classes));
        Class tic = Proxy.getProxyClass(
                Test.class.getClassLoader(), Test.class);
        System.out.println("just generated: " + tic);
        classes = getAllClassesAssignableFrom(Test.class);
        System.out.println("classes found: " + Arrays.toString(classes));
    }

}

piotr
opalpa opalpa@gmail.com http://opalpa.info - 10 Oct 2006 14:40 GMT
Good thinking.

The only catch is loading them first.

opalpa
opalpa@gmail.com
http://opalpa.info/


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.