Working with Module System Advanced
1. Understanding Module Layers
| Layer | Detail |
|---|---|
| Boot layer | Created by JVM at startup |
ModuleLayer.boot() | Access boot layer |
| Custom layers | Plugin systems, hot reload |
| Parent | Layer can have multiple parents |
2. Creating Custom Module Layers
Example: Plugin layer
ModuleFinder finder = ModuleFinder.of(Path.of("plugins"));
ModuleLayer parent = ModuleLayer.boot();
Configuration cfg = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("plugin.foo"));
ModuleLayer layer = parent.defineModulesWithOneLoader(cfg, ClassLoader.getSystemClassLoader());
ServiceLoader.load(layer, Plugin.class).forEach(Plugin::start);
3. Using ModuleFinder API
| API | Use |
|---|---|
ModuleFinder.of(paths...) | From file paths |
ModuleFinder.ofSystem() | JDK modules |
findAll() / find(name) | List or lookup |
compose(...) | Combine finders |
4. Using ModuleDescriptor
| API | Returns |
|---|---|
name() / version() / mainClass() | Identity |
requires() / exports() / opens() | Directives |
provides() / uses() | Services |
packages() | All packages |
5. Using Configuration API
| API | Use |
|---|---|
Configuration.resolve(finder, parent, roots) | Build graph |
resolveAndBind(...) | Also bind services |
findModule(name) | Lookup resolved module |
6. Working with Layered Modules
| Method | Use |
|---|---|
defineModulesWithOneLoader(cfg, parentCL) | Single loader |
defineModulesWithManyLoaders(cfg, parentCL) | One loader per module |
defineModules(cfg, mapper) | Custom mapper |
| Use | Plugin isolation, hot reload |
7. Using ModuleReader
| API | Use |
|---|---|
module.reference().open() | Open ModuleReader |
list() | Stream of resource names |
open(resName) / read(resName) | InputStream / ByteBuffer |
| Close | AutoCloseable |
8. Implementing Module Resolution
| Aspect | Detail |
|---|---|
| Algorithm | BFS from roots, follow requires |
| Errors | FindException / ResolutionException |
| Service binding | Optional second pass for uses |
9. Understanding Strong Encapsulation
| Java Version | Default |
|---|---|
| 9–15 | --illegal-access=permit |
| 16+ | --illegal-access=deny default |
| 17+ | Flag removed; only --add-opens works |
| 21+ | Strict; agents must declare EnableNativeAccess |
10. Using --add-opens and --add-exports
| Flag | Format |
|---|---|
--add-opens | module/package=ALL-UNNAMED |
--add-exports | module/package=target |
--add-reads | source=target |
| Manifest | Add-Opens attribute (executable JAR) |
11. Creating Modular Applications with jlink
| Flag | Use |
|---|---|
--module-path | Where modules live |
--add-modules M | Roots |
--launcher name=M/Main | Launcher script |
--compress=zip-9 | Java 21+ compression |
--strip-debug --no-header-files --no-man-pages | Minimize size |