List All Classes In A Package

J

Jason Teagle

Java 1.4.x

Is it possible to get a list of all classes a package contains, either by
name (Strings) or as an array of Class object references? I've looked
through Class, ClassLoader and Package and can't seem to see a way.

* Class.getClasses() only returns the classes defined publicly within a
class, so not what I am looking for.
* Package.getPackages() only lists what packages are available that use the
current class loader, but I already know what packages I want to list
classes from.

If I had a package representing javax.swing, I'm looking to be able to get
"JButton", "JCheckbox", "JList", etc from it.

Any ideas?
 
M

Michael Borgwardt

Jason said:
Java 1.4.x

Is it possible to get a list of all classes a package contains, either by
name (Strings) or as an array of Class object references? I've looked
through Class, ClassLoader and Package and can't seem to see a way.

Because there is no way. It is theoretically impossible due to the
flexivle ClassLoader concept. Classes can be loaded from remote
servers or even generated on the fly - no way to know what classes
exist or even whether a specific class exists until you've asked for
a specific class by name.
 
C

Chris Smith

Jason said:
Java 1.4.x

Is it possible to get a list of all classes a package contains, either by
name (Strings) or as an array of Class object references? I've looked
through Class, ClassLoader and Package and can't seem to see a way.

There is no way to do that.

This is by design, because it allows ClassLoader uses that would
otherwise be impossible. For one example, the HTTP protocol allows you
to request any class file and get back the data or a 404 error, but it
doesn't allow you get a list of the files in a directory. If it were
possible to list classes in a package, it would be impossible to define
a ClassLoader that uses HTTP to retrieve class data.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jason Teagle

There is no way to do that.
This is by design, because it allows ClassLoader uses that would
otherwise be impossible. For one example, the HTTP protocol allows you
to request any class file and get back the data or a 404 error, but it
doesn't allow you get a list of the files in a directory. If it were
possible to list classes in a package, it would be impossible to define
a ClassLoader that uses HTTP to retrieve class data.

Oh dear. Thanks for the info.
 
J

Jason Teagle

Because there is no way. It is theoretically impossible due to the
flexivle ClassLoader concept. Classes can be loaded from remote
servers or even generated on the fly - no way to know what classes
exist or even whether a specific class exists until you've asked for
a specific class by name.

Oh dear. Thanks for the info.
 
A

Andrew Thompson

Is it possible to get a list of all classes a package contains, ..

Not really, as both Michael and Chris pointed out (dynamically
created classes, possibly classes loaded by an URLClassLoader),
but if the classes are on a file-system or in a local jar, it
is certainly possible to list the classes *currently* within
a particular package who's location is known.

The more important question though, is why you *think*
you need to do this. What do you want to achieve?

--
Andrew Thompson
http://www.PhySci.org/codes/ Web & IT Help
http://www.PhySci.org/ Open-source software suite
http://www.1point1C.org/ Science & Technology
http://www.lensescapes.com/ Images that escape the mundane
 
J

Jason Teagle

but if the classes are on a file-system or in a local jar, it
is certainly possible to list the classes *currently* within
a particular package who's location is known.

Indeed it is possible, I found a way to do just that...
The more important question though, is why you *think*
you need to do this. What do you want to achieve?

I wanted to present to the user a list of all classes [supported by their
installation of Java] that extend Component, rather than present them with a
fixed list that may be out of date as Java develops and adds new Swing
component classes (for once I was actually thinking into the future).

Much the same as when you create a new class in Eclipse, and it presents a
list of known classes from which your class could extend.
 
G

Gary Labowitz

Jason Teagle said:
but if the classes are on a file-system or in a local jar, it
is certainly possible to list the classes *currently* within
a particular package who's location is known.

Indeed it is possible, I found a way to do just that...
The more important question though, is why you *think*
you need to do this. What do you want to achieve?

I wanted to present to the user a list of all classes [supported by their
installation of Java] that extend Component, rather than present them with a
fixed list that may be out of date as Java develops and adds new Swing
component classes (for once I was actually thinking into the future).

Much the same as when you create a new class in Eclipse, and it presents a
list of known classes from which your class could extend.

Doesn't Javadocs do exactly this, and more?
 
J

Jason Teagle

Much the same as when you create a new class in Eclipse, and it presents
Doesn't Javadocs do exactly this, and more?

I believe it does - but since I need this to happen at run time, I'm
assuming I can't use javadocs for this in any way? (Not being facetious, I
don't know, there may be some hidden class in Java that supports javadocs
functionality!).
 
G

Gary Labowitz

Jason Teagle said:
I believe it does - but since I need this to happen at run time, I'm
assuming I can't use javadocs for this in any way? (Not being facetious, I
don't know, there may be some hidden class in Java that supports javadocs
functionality!).

I'm not trying to be funny, but does Eclipse do this at run-time? Or are you
just saying you want to do this at run-time as it is done by Eclipse at
development time?
In any event, can you get fully qualified name from Class? Would that help?
 
S

steve

Java 1.4.x

Is it possible to get a list of all classes a package contains, either by
name (Strings) or as an array of Class object references? I've looked
through Class, ClassLoader and Package and can't seem to see a way.

* Class.getClasses() only returns the classes defined publicly within a
class, so not what I am looking for.
* Package.getPackages() only lists what packages are available that use the
current class loader, but I already know what packages I want to list
classes from.

If I had a package representing javax.swing, I'm looking to be able to get
"JButton", "JCheckbox", "JList", etc from it.

Any ideas?


yes it is possible!!!. ( think de-compiler)
even for remote classes.
if it was not possible,
how the hell could the JVM work???
it clearly states that the JVM MUST resolve all references to a class ,before
it starts execution.

or are people saying , that the JVM on my machine starts executing a class
BEFORE it has resolved any /all references.

as for webcalls for classes, THEY ARE DOWNLOADED to the local jvm, to become
available.

RMI might be an exception , but you still have the stubs.



steve
 
M

Michael Borgwardt

steve said:
yes it is possible!!!. ( think de-compiler)

No, it's not.
even for remote classes.
if it was not possible,
how the hell could the JVM work???

It doesn't need to "list all classes in a package".
it clearly states that the JVM MUST resolve all references to a class ,before
it starts execution.

And your point is...?
or are people saying , that the JVM on my machine starts executing a class
BEFORE it has resolved any /all references.

No. They are saying that the ClassLoader concept allows only the query
for classes by their complete, fully qualified name. The response to
such a query is either the class queried for, or an exception indicating
that no class with that name could be found or that it was defective.

This mechanism does not make it possible to list all classes in a package
except by trying all possible class names, which is a literally infinite
number since class names are identifiers and the language specification
places no length restriction on identifiers.
 
Joined
Jun 14, 2008
Messages
1
Reaction score
0
Simple Answer is to do the following:

// (credit to => http://snippets.dzone.com/posts/show/4831)
// I'm not the author but this works real well

Code:
/**
     * Scans all classes accessible from the context class loader which belong to the given package and subpackages.
     *
     * @param packageName The base package
     * @return The classes
     * @throws ClassNotFoundException
     * @throws IOException
     */
    private static Class[] getClasses(String packageName)
            throws ClassNotFoundException, IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        assert classLoader != null;
        String path = packageName.replace('.', '/');
        Enumeration<URL> resources = classLoader.getResources(path);
        List<File> dirs = new ArrayList<File>();
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            dirs.add(new File(resource.getFile()));
        }
        ArrayList<Class> classes = new ArrayList<Class>();
        for (File directory : dirs) {
            classes.addAll(findClasses(directory, packageName));
        }
        return classes.toArray(new Class[classes.size()]);
    }

    /**
     * Recursive method used to find all classes in a given directory and subdirs.
     *
     * @param directory   The base directory
     * @param packageName The package name for classes found inside the base directory
     * @return The classes
     * @throws ClassNotFoundException
     */
    private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
        List<Class> classes = new ArrayList<Class>();
        if (!directory.exists()) {
            return classes;
        }
        File[] files = directory.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                assert !file.getName().contains(".");
                classes.addAll(findClasses(file, packageName + "." + file.getName()));
            } else if (file.getName().endsWith(".class")) {
                classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
            }
        }
        return classes;
    }
 

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

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top