Java Modules System
In this page:
module module.name {
requires other.module;
exports package.name;
}
Introduction to Modules
The Java Module System, originally developed under Project Jigsaw, lets you group related packages into a single, reusable module with explicit, declared dependencies. It also lets a module limit which of its internal packages are visible to the outside world, improving both security and startup performance by avoiding scanning the entire classpath.
Example: Introduction to Modules
public class Main {
public static void main(String[] args) {
// A module groups packages with explicit, declared dependencies (see module-info.java)
System.out.println("Module system groups related packages together");
}
}
Login to try C/C++/Java/PHP code in the editor
Module Descriptors
A module is defined by a module-info.java file placed at its root, which specifies which of the module's packages it exports for other modules to use, and which other modules it in turn requires to compile and run.
Example: Module Descriptors
public class Main {
public static void main(String[] args) {
// module-info.java would declare:
// module com.example.app {
// exports com.example.app.api;
// requires java.sql;
// }
System.out.println("module-info.java declares exports and requires");
}
}
Login to try C/C++/Java/PHP code in the editor
Loading Platform Modules
You can query the running JVM to enumerate all currently loaded platform modules, which is a useful way to understand exactly which parts of the JDK a given application actually has access to at runtime.
Example: Loading Platform Modules
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
// Create a stream from the collection to process it step by step
ModuleLayer.boot().modules().stream()
.limit(3)
.forEach(m -> System.out.println(m.getName()));
}
}
Login to try C/C++/Java/PHP code in the editor
Service Loader API
The Module System integrates directly with the existing ServiceLoader API, letting modules explicitly declare which services they provide and which they consume. This keeps the modules loosely coupled, since a consuming module never needs to know the concrete class of the service it's using.
Example: Service Loader API
import java.util.ServiceLoader;
public class Main {
interface Greeter {
String greet();
}
static class EnglishGreeter implements Greeter {
public String greet() { return "Hello"; }
}
public static void main(String[] args) {
Greeter g = new EnglishGreeter(); // ServiceLoader.load(Greeter.class) would discover providers declared in module-info.java
System.out.println(g.greet());
}
}
Login to try C/C++/Java/PHP code in the editor
Module Layer API
You can inspect the active module layers within a running JVM, where each layer represents a graph of already-resolved modules along with the class loaders responsible for loading them, which is mostly relevant when building plugin-style or modular application architectures.
Example: Module Layer API
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
ModuleLayer bootLayer = ModuleLayer.boot();
// Print a line to the console
System.out.println("Boot layer module count: " + bootLayer.modules().size());
}
}
Login to try C/C++/Java/PHP code in the editor
- Forgetting to
exportsa package inmodule-info.java, so other modules cannot see its classes even if they are public. - Using another module's classes without a matching
requiresline, which gives a 'package is not visible' compile error. - Expecting reflection to reach private members of a module, when you must
opensthe package for frameworks that use reflection.
Chapter Quiz — Complete all 12 topics to unlock
0/12 topics done
Complete these topics first: