Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 516
mpobrien Avatar asked Nov 29 '09 20:11

mpobrien


People also ask

Who loads the ClassLoader?

3.3. In addition, children class loaders are visible to classes loaded by their parent class loaders. For instance, classes loaded by the system class loader have visibility into classes loaded by the extension and bootstrap class loaders, but not vice-versa.

Is it possible to load a class by two ClassLoader?

A class is always identified using its fully qualified name (package. classname). So when a class is loaded into JVM, you have an entry as (package, classname, classloader). Therefore the same class can be loaded twice by two different ClassLoader instances.

How do I know what ClassLoader loads a class?

To know the ClassLoader that loads a class the getClassLoader() method is used. All classes are loaded based on their names and if any of these classes are not found then it returns a NoClassDefFoundError or ClassNotFoundException.

What is class unloading?

Class unloading is a desirable optimization feature for any Java Virtual Machine implementation. Similar to normal garbage collection, class unloading is the process of freeing memory occupied by various loaded classes that are no longer referenced by the current program execution context.


1 Answers

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.

like image 86
Adriaan Koster Avatar answered Oct 18 '22 21:10

Adriaan Koster