← Back to Advanced Java Course | Chapter 4: Modern Java Features | Lesson 8 of 12

Java Modules System

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

java
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");
	}
}

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

java
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");
	}
}

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

java
public class Main {
	public static void main(String[] args) {
		ModuleLayer.boot().modules().stream()
			.limit(3)
			.forEach(m -> System.out.println(m.getName()));
	}
}

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

java
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());
	}
}

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

java
public class Main {
	public static void main(String[] args) {
		ModuleLayer bootLayer = ModuleLayer.boot();
		System.out.println("Boot layer module count: " + bootLayer.modules().size());
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.