What's the relationship between a Module and a ClassLoader as per Project Jigsaw?
Does each module have its own unique ClassLoader?
How do I get all the classes inside a module?
What's the relationship between a Module and a ClassLoader as per Project Jigsaw?
Does each module have its own unique ClassLoader?
How do I get all the classes inside a module?
A module is loaded by a single class loader, but a class loader may be responsible for an arbitrary number of modules.
The built-in modules are all loaded by one or two class loaders, the Bootstrap class loader and Platform class loader. The application specific modules specified at startup, are all loaded by the System class loader, also known as Application class loader. These three Built-in Class Loaders load the classes of all modules belonging to the boot layer
When you create a new module layer, you can demand that each of its modules is loaded by a distinct class loader using a convenience method but requesting the loading of all modules by a single loader is equally simple. There is a method taking a function to map each module name to a class loader, allowing more elaborated setups like that of the boot layer, however, it still has map one particular module to one loader. So it’s still as said at the beginning, one module will be loaded by one loader, but one loader may be responsible for multiple modules.
The class loading still is dynamic in Java, so we can’t say for sure, how many classes will be inside a module, but the packages belonging to a module are fixed. So you can easily query those packages.
Module m = Object.class.getModule(); // java.base
// using java.compiler as an example with not so many packages
m = m.getLayer().findModule("java.compiler").orElseThrow();
m.getPackages().forEach(System.out::println);
javax.lang.model
javax.lang.model.type
javax.tools
javax.lang.model.util
javax.lang.model.element
javax.annotation.processing
You may query the module’s storage for the existing class files, which may give you an estimate of the classes which might exist in a module, but as said, class loading is dynamic, so there might be more classes at runtime, not having a persistent storage.
List<String> classNames;
try(var reader = m.getLayer().configuration()
.findModule(m.getName()).orElseThrow().reference().open()) {
classNames = reader.list()
.filter(s -> s.endsWith(".class"))
.map(s -> s.substring(0, s.length() - ".class".length()).replace('/', '.'))
.toList();
}
classNames.forEach(System.out::println);