Search code examples
javaclasspackageclassloader

Is there a way to force a classloader to load a package even if none of its classes have been loaded?


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?


Solution

  • 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);
    }