Getting a list of all classes in a package

S

sarek

I need some method that will by using reflection alone tell me every
class in a given package. Specifically if I have a package called
UnitTest and want to get
a list of all classes that have TestCase as there base class.

--Aryeh
 
P

Paul Cager

sarek said:
I need some method that will by using reflection alone tell me every
class in a given package. Specifically if I have a package called
UnitTest and want to get
a list of all classes that have TestCase as there base class.

--Aryeh

This topic has come up a few times before. It is not possible to do it
in general, although there are approaches that "nearly" work.

Have a look at the threads titled "List All Classes In A Package" and
"how to list classes or subpackages in a package" in this newsgroup.
 
S

sarek

This topic has come up a few times before. It is not possible to do
it
in general, although there are approaches that "nearly" work.
Have a look at the threads titled "List All Classes In A Package" and
"how to list classes or subpackages in a package" in this newsgroup.

None of those really helped I guess the best solution I can think of is
to read the package dir/jar and pickout any class that inherits the
desired base class. Even though I see why this is theortically
impossible for how the vm is currently implimented I do not see why it
is not possible for a theortical vm.

--Aryeh
 
T

Tor Iver Wilhelmsen

sarek said:
I need some method that will by using reflection alone tell me every
class in a given package.

You cannot, because "packages" as such don't exist in the VM. A given
loaded class has its "package" as part of the fully qualified class
name. But that "package" can contain classes that haven't been loaded
yet, and there is no way for reflection to find these.

The closest thing you get is to traverse the classpath using File and
ZipEntry, looking at all files ending in .class, analyzing the names
to see if there are any nested classes.
 
T

Thomas Weidenfeller

sarek said:
Even though I see why this is theortically
impossible for how the vm is currently implimented I do not see why it
is not possible for a theortical vm.

Only if your "theoretical VM" is powered by a significant amount of
black magic. Class data can come from almost any sources, like e.g. byte
arrays or URLs.

For byte arrays your "theoretical VM" has to look into the future to
know all the classes someone will assemble in a byte array and load via
a class loader during the runtime of your application.

For URLs the URL class loader has no means to query a remote HTTP
server's contents - it is not part of the protocol. So the class loader,
and thus your "theoretical VM" can never get a list of available class
files on that server.

It has all been discussed again and again here. Please follow the advice
and read the previous discussions.

/Thomas
 
S

sarek

Here is my current naive solution please point out any issues you see
(except for the obvious hardcoding the classpath, package name and not
using jar's):

package sdc.unittest;

import java.io.*;
import java.lang.reflect.*;

public class TestRunner {
public static TestRunner init()
{
return new TestRunner();
}

public void run()
{
int i;

for(i=0;i<MaxTests;i++)
TestCases.run();
}

public TestRunner()
{
MaxTests=0;
scanDir(System.getProperty("java.class.path"));
}

private void scanDir(String dir)
{
File root=new File(dir);
String [] files=root.list();
int i=0;
File file;

for(i=0;i<files.length;i++) {
file=new File(dir,files);

if(file.isDirectory()==true) {
dir+=File.separator+files;
scanDir(dir);
continue;
}

if(files.endsWith(".class")==true)
scanClass(dir,

files.substring(0,files.lastIndexOf('.')));
}
}

private void scanClass(String dir, String klass)
{
Class bClass;
Class rClass;
Package bPackage;
Method method;

try {
rClass=Class.forName(getrClassName(dir,klass));

bClass=rClass.getSuperclass();
bPackage=bClass.getPackage();


if(bClass.getName().equals("sdc.unittest.TestCase")==true) {
method=rClass.getMethod("init",null);

TestCases[MaxTests++]=(TestCase)
method.invoke("init",
null);
}
} catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}

private String getrClassName(String dir,String klass)
{
return
(dir.substring(dir.lastIndexOf(File.separator+File.separator)
+2)).replace(File.separatorChar,'.')+"."+klass;
}


private TestCase [] TestCases = new TestCase[CaseLimit];
private int MaxTests;
private static int CaseLimit=1024;
}
 
L

Lee Fesperman

sarek said:
Here is my current naive solution please point out any issues you see
(except for the obvious hardcoding the classpath, package name and not
using jar's):

You're also not supporting zip files. I just gave it a quick glance and ...
scanDir(System.getProperty("java.class.path"));
}

private void scanDir(String dir)
{
File root=new File(dir);
String [] files=root.list();

Here you are assuming that the classpath consists of a single entry. The classpath may
contain a list of entries separated by path.separator.
 

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,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top