views:

322

answers:

2

Let's say a java codebase has a package called "com.example".

At runtime, we can get this Package by calling

Package p = Package.getPackage( "com.example" ); //(returns null)

or even get a list of all packages by calling

Packages[] ps = Package.getPackages();

The problem is - if the ClassLoader has not yet loaded any class from the package, it won't be available to these function calls. We can force it to load the package by force-loading one of the classes in the package first, like this:

this.getClass().getClassLoader().loadClass( "com.example.SomeClass" );
Package p = Package.getPackage( "com.example" ); //(returns non-null)

However, this is hacky and requires knowing ahead of time the name of some class that belongs to the package.

So the question is - is there any way to get an instance of Package by name, regardless of whether or not the ClassLoader has done anything? Are my assumptions about how classloading/packages seem to work in this situation accurate?

+4  A: 

I'm afraid that your assumptions are not valid. Classloaders do package book-keeping as they load classes.

You can pass a wildcard to ClassLoader.getResources and force it to pick up the classes in a package, which will in turn do the work.

You can make your own ClassLoader that calls definePackage, but that won't help you with the usual vanilla classloaders in use.

bmargulies
+2  A: 

Alternatively you could use the class root directory as a starting point and walk through all *.class files and sub directories. This would only work if you know where all your .class files will reside beforehand.

The cause of all this is that Java has dynamic classloading, so classes can be loaded at runtime from locations not known at compile time or even at startup time. Therefore the concept of a package is just a namespace for loaded classes, not a directory which you can use to look them up.

Adriaan Koster