100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Java Mastery
35 minintermediate

The Java Module System (JPMS)

As Java applications grew to hundreds of packages and many dependencies, two long-standing weaknesses became painful: there was no way to truly hide internal packages (public meant public to the entire world, even across libraries), and the classpath was a flat, unverified list where missing or conflicting JARs failed only at runtime, the infamous JAR hell. The Java Platform Module System (JPMS), introduced in Java 9, addresses both by adding modules: named, self-describing units of code with explicit dependencies and explicit exports.

A module is a group of packages plus a module-info.java descriptor that declares what the module requires (its dependencies on other modules) and what it exports (the packages it makes available to others), with everything else strongly encapsulated and inaccessible from outside. The JVM and compiler use these declarations to build a verified module graph, catching missing or conflicting dependencies up front rather than at runtime.

Understanding the module system matters because it raised encapsulation and dependency management to the level of whole libraries, the JDK itself is now modular, and it changes how large applications are structured and how strongly their internals are protected. Even though many applications still run on the classpath, knowing what modules are, why they exist, and how requires and exports work is essential for understanding modern Java's architecture and for working with the modular JDK.

Analogy🏏Cricket
🏏 Think of it like cricket: a team sheet does not just list players, it assigns each to a precise, declared role, opener, spinner, wicketkeeper, and the laws and the captain enforce that a player operates within their declared role: you cannot send a designated bowler to keep wicket without an official change. Just as each player's role is fixed and checked before play, each Java variable's type is fixed at compile time and checked by the compiler. Just as trying to use a player outside their role is caught by the officials before it disrupts the match, using a variable in a type-incompatible way is caught by the compiler before the program runs. Just as clear role assignments prevent on-field confusion, clear type declarations prevent runtime errors. The insight is that declaring and enforcing roles up front, for players or for data, catches mistakes early rather than mid-match.
Lesson 27 of 35
0% complete