Working with Module System Advanced

1. Understanding Module Layers

LayerDetail
Boot layerCreated by JVM at startup
ModuleLayer.boot()Access boot layer
Custom layersPlugin systems, hot reload
ParentLayer 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

APIUse
ModuleFinder.of(paths...)From file paths
ModuleFinder.ofSystem()JDK modules
findAll() / find(name)List or lookup
compose(...)Combine finders

4. Using ModuleDescriptor

APIReturns
name() / version() / mainClass()Identity
requires() / exports() / opens()Directives
provides() / uses()Services
packages()All packages

5. Using Configuration API

APIUse
Configuration.resolve(finder, parent, roots)Build graph
resolveAndBind(...)Also bind services
findModule(name)Lookup resolved module

6. Working with Layered Modules

MethodUse
defineModulesWithOneLoader(cfg, parentCL)Single loader
defineModulesWithManyLoaders(cfg, parentCL)One loader per module
defineModules(cfg, mapper)Custom mapper
UsePlugin isolation, hot reload

7. Using ModuleReader

APIUse
module.reference().open()Open ModuleReader
list()Stream of resource names
open(resName) / read(resName)InputStream / ByteBuffer
CloseAutoCloseable

8. Implementing Module Resolution

AspectDetail
AlgorithmBFS from roots, follow requires
ErrorsFindException / ResolutionException
Service bindingOptional second pass for uses

9. Understanding Strong Encapsulation

Java VersionDefault
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

FlagFormat
--add-opensmodule/package=ALL-UNNAMED
--add-exportsmodule/package=target
--add-readssource=target
ManifestAdd-Opens attribute (executable JAR)
FlagUse
--module-pathWhere modules live
--add-modules MRoots
--launcher name=M/MainLauncher script
--compress=zip-9Java 21+ compression
--strip-debug --no-header-files --no-man-pagesMinimize size
jlink --module-path $JAVA_HOME/jmods:mods \
      --add-modules com.acme.app \
      --launcher app=com.acme.app/com.acme.Main \
      --strip-debug --compress=zip-9 \
      --output build/app-runtime