One of the first surprises developers encounter when working with the Java Platform Module System (JPMS) is that even the JDK itself is modularized. Many mistakenly assume that all JDK classes are automatically available. In reality, every program depends on java.base
implicitly, but other modules like java.sql
, java.xml
, or java.desktop
must be explicitly required in module-info.java
.
This misunderstanding often leads to “package not found” or “package not visible” errors when migrating code from classpath to module path. Understanding how JDK modules are structured is critical for writing modular applications, whether for enterprise systems, microservices, or cloud-native apps.
Think of JDK modules as departments in a company headquarters. The java.base
department provides essentials (like HR, accounting, and security) that everyone uses. But specialized departments like java.sql
(databases) or java.desktop
(UI) must be explicitly consulted if your project needs them.
Core JDK Modules
1. java.base
- Always available (implicitly required by all modules)
- Contains fundamental APIs:
java.lang
,java.util
,java.io
,java.net
,java.time
Example:
module com.example.app {
// no need to declare requires java.base;
}
2. java.sql
- Provides JDBC APIs for database access
- Must be explicitly declared if using JDBC
module com.example.dbapp {
requires java.sql;
}
3. java.xml
- APIs for XML parsing (DOM, SAX, StAX, XPath)
- Useful in web services and data integration
module com.example.xmlapp {
requires java.xml;
}
4. java.desktop
- Swing and AWT APIs for GUI applications
- Often used in JavaFX interoperability
module com.example.guiapp {
requires java.desktop;
}
5. java.logging
- Provides
java.util.logging
framework - Lightweight logging compared to external frameworks
module com.example.loggingapp {
requires java.logging;
}
6. java.management
- APIs for monitoring and management via JMX
- Useful in enterprise monitoring solutions
module com.example.monitoring {
requires java.management;
}
Dependency Management in JDK Modules
Example: Application with database + logging
module com.example.orderservice {
requires java.sql;
requires java.logging;
exports com.example.orderservice.api;
}
java.base
is implicitjava.sql
→ enables JDBCjava.logging
→ enables logging
Pitfalls When Using JDK Modules
❌ Forgetting to declare requires java.sql
when using JDBC APIs
❌ Assuming java.xml
is available without declaring it
❌ Overusing transitive requires (requires transitive java.sql
) → leaks dependencies unnecessarily
❌ Mixing classpath and module path → leads to class visibility issues
Best Practices
✅ Always explicitly declare required JDK modules (except java.base
)
✅ Use jdeps
to analyze dependencies
✅ Prefer requires
over requires transitive
unless absolutely needed
✅ Keep module-info.java
minimal and clean
✅ Test applications on the module path, not just classpath
What's New in Java Versions?
- Java 5–8 → N/A (no modules)
- Java 9 → JDK modularized (
java.base
,java.sql
,java.xml
, etc.) - Java 11 → Removed Java EE modules (like
java.corba
,java.xml.ws
) - Java 17 → Performance improvements in module resolution
- Java 21 → No significant updates across Java versions for this feature
Real-World Analogy
Working with JDK modules is like choosing departments in a corporate office. Every employee uses HR (java.base
). If you need financial audits (java.sql
), you call that department specifically. If not, it remains idle and doesn’t burden the company.
Summary & Key Takeaways
- The JDK itself is modularized into components like
java.base
,java.sql
,java.xml
,java.desktop
java.base
is always available, others must be explicitly required- Tools like
jdeps
help discover dependencies - Explicit modularization improves performance and reduces runtime footprint
- Declaring correct modules prevents runtime errors and improves maintainability
FAQ: JDK Modules
1. What is the difference between classpath and module path?
Classpath loads all classes blindly, module path enforces explicit dependencies.
2. Why do I get “package not visible” errors?
Because the required JDK module isn’t declared in module-info.java
.
3. What is the purpose of requires transitive
in JDK modules?
It makes dependencies available to downstream modules but should be used sparingly.
4. How do open
and opens
differ in JDK modules?open
exposes the entire module, while opens
grants reflection access only to specified packages.
5. Are automatic modules useful when dealing with JDK modules?
They help migrate third-party JARs, but JDK modules are explicit and don’t need them.
6. How does JPMS improve security with JDK modules?
It enforces encapsulation and prevents accidental use of internal APIs.
7. Should I use jlink or jmod with JDK modules?
Use jlink
for custom runtimes, jmod
for distributing libraries.
8. Can I migrate legacy applications using JDK modules incrementally?
Yes, start with --add-modules
and gradually introduce module-info.java
.
9. How do I handle third-party non-modular libraries with JDK modules?
Use them as automatic modules or place them on the classpath.
10. Do frameworks like Spring and Hibernate require explicit JDK modules?
Yes, they need opens
for reflection and require JDK modules like java.sql
.