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?
I assume you need this because you need to inspect its annotations. Otherwise you wouldn't be interested in having a Package reference which only operations are all around accessing annotations. This leads to the assumtion that you also have a package-info.java defined there with some annotations.
If you check java.lang.Package
you'll see that the getPackageInfo
just loads the package-info class as an ordinary class.
I had the same problem and came up with this solution.
public static Package getPackage(String packageName) throws ClassNotFoundException {
Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package
return Package.getPackage(packageName);
}