Runtime relationship between class loaders and Java SE 9 modules

The Java SE 9 module system, or Jigsaw, works at both compile-time and run-time. At run-time, Jigsaw must work well together with the old class loader mechanism, without breaking existing applications. It has resulted odd and subtle relationship between them.

The diagram represents the relationships among class loaders, modules and related components in the IDEF1X syntax.

Classes, packages and class loaders

These components exist from Java SE 8 and earlier, and work the same way on Java SE 9.

(1) When a class is defined in a class loader, the class is bound to a runtime package determined by the name and the defining class loader.

(2) A runtime package is determined by the pair of the name and the class loader, which defines classes beloging to the package.

Modules and module layers

(3) On Java SE 9, a runtime package is bound to a runtime module.

(4) There is two subtypes of modules: named and unnamed *1.

(5) When a ModuleLayer is created invoking ModuleLayer.defineModules, a set of named modules are crated in accord with the configuration, and bound to the ModuleLayer.

(6) A named module has an immutable set of packages, which is specified in its ModuleDescriptor.
(7) And the named module is bound to a class loader specified by the invocation of ModuleLayer.defineModules.

A class loader cannot be bound to by multiple named modules which contain an overlapping set of packages, because a package cannot split across multiple modules. Hence ModuleLayer.defineModules checks invariants to avoid such situation, and throws LayerInstantiationException if any violation is detected. For example, if a class loader has already defined the class org.example.Foo, ModuleLayer.defineModules cannot map a module which contains the package org.example to the class loader.

(8) A class loader has an unnamed module. When a class is defined in a class loader, and its package is not bound to any named module bound to the class loader, the package is bound to the unnamed module of the class loader. Note that unnamed modules are not bound to any module layer.

There is no direct restrictions for the relationship between class loaders and module layers. For example, a class loader may define classes in multiple module layers (JVMS9 §5.3.6), though there is no practical use case for such a configuration.

*1:The term “named module” is implicitly defined in Javadoc of ModuleDescriptor.