views:

2114

answers:

5

Hi, i need to read classes contained in a java package. Those classes are in classpath. I need to do this task from java program directly. Do you know a simple way to do?

List classes = readClassesFrom("my.package")

A: 

That functionality is still suspiciously missing from the Java reflection API as far as I know. You can get a package object by just doing this:

Package packageObj = Package.getPackage("my.package");

But as you probably noticed, that won't let you list the classes in that package. As of right now, you have to take sort of a more filesystem-oriented approach.

I found some sample implementations in this post:

http://forums.sun.com/thread.jspa?threadID=341935

I'm not 100% sure these methods will work when your classes are buried in JAR files, but I hope one of those does it for you.

I agree with @skaffman...if you have another way of going about this, I'd recommend doing that instead.

Brent Nash
It's not suspicious, it just doesn't work that way. Classes don't "belong" to packages, they have references to them. The association doesn't point in the other direction.
skaffman
@skaffman Very interesting point. Never thought about it that way. So as long as we're wandering down that trail of thought, why is the association not bi-directional (this is more for my own curiosity now)?
Brent Nash
+1  A: 

Brent - the reason the association is one way has to do with the fact that any class on any component of your CLASSPATH can declare itself in any package (except for java/javax). Thus there just is no mapping of ALL the classes in a given "package" because nobody knows nor can know. You could update a jar file tomorrow and remove or add classes. It's like trying to get a list of all people named John/Jon/Johan in all the countries of the world - none of us is omniscient therefore none of us will ever have the correct answer.

idarwin
A: 

Back when applets were common place, one might have a URL on the classpath. When the classloader required a class, it would search all the locations on the classpath, including http resources. Because you can have things like URLs and directories on the classpath, there is no easy way to get a definitive list of the classes.

However, you can get pretty close. Some of the Spring libraries are doing this now. You can get all the jar's on the classpath, and open them up like files. You can then take this list of files, and create a data structure containing your classes.

brianegge
+2  A: 

I happen to have implement it and it works in most cases. Since it is long so I put it in a file here.

The idea is to find the location of the class source file which available in most case (a known exception is JVM class files -- as far as I've tested). If the code is in a directory, scan through all files and only spot class files. If the code is in a Jar file, scan all entries.

This method can only be use when:

  1. You have a class that is in the same package you want to discover, This class is call a SeedClass. For example, if you want to list all class in 'java.io', the seed class may be java.io.File.

  2. You classes are in a directory or in a Jar file is has Source file information (not source code file but just source file). As far as I've tried, it work almost 100% except the JVM class (those class comes with JVM).

  3. Your program must have permission to access ProtectionDomain of those classes. If your program is loaded locally, there should be no problem.

I've test the program only for my regular usage so it may still have problem.

Hope this helps.

NawaMan
it appear to be a very interesting stuff! i will try to use it. If i found helpful for me, can i use your code in an open source project?
Luca Marrocco
I am preparing to open-source it too. So go ahead :D
NawaMan
A: 

Spring has implemented an excellent classpath search function in the PathMatchingResourcePatternResolver. If you use the classpath*: prefix, you can find all the resources, including classes in a given hierarchy, and even filter them if you want. Then you can use the children of AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter and AssignableTypeFilter to filter those resources either on class level annotations or on interfaces they implement.

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/core/io/support/PathMatchingResourcePatternResolver.html

http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/core/type/filter/AbstractTypeHierarchyTraversingFilter.html

John Ellinwood