Study guide
10.2 Module Directives: requires, exports, opens, provides, and uses
Oracle Java SE 21 Developer 1Z0-830
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: Java Basics, Primitive Types, and Operators
1.1 Program Structure, Primitives, Literals, Scopes, and var 1.2 Operators, Precedence, and Type Casting 1.3 Strings, Text Blocks, and StringBuilder 1.4 Date and Time APIs (java.time)
2 Chapter 2: Controlling Program Flow & Pattern Matching
2.1 Conditional Logic: if-else and Ternary Operators 2.2 Switch Statements and Switch Expressions 2.3 Pattern Matching for switch and instanceof 2.4 Loops and Branching Statements
3 Chapter 3: Object-Oriented Design & Class Architecture
3.1 Class Declarations, Constructors, and Object Lifecycle 3.2 Encapsulation and Access Modifiers 3.3 Inheritance, Method Overriding, and Polymorphism 3.4 Abstract Classes and Interfaces 3.5 Nested, Inner, Local, and Anonymous Classes 3.6 Method Overloading, Overload Resolution, and Varargs
4 Chapter 4: Modern Java Data Modeling: Records, Enums, and Sealed Types
4.1 Java Records, Canonical/Compact Constructors, and Component Accessors 4.2 Java Enums: Fields, Methods, and Abstract Constant-Specific Behavior 4.3 Sealed Classes and Interfaces: permits, final, non-sealed, and Hierarchy Architecture 4.4 Advanced Record Patterns (JEP 440), Nested Deconstruction, and Sealed Hierarchy Exhaustiveness
5 Chapter 5: Exception Handling and Annotations
5.1 Exception Hierarchy: Checked vs. Unchecked Exceptions 5.2 Exception Handling: try, catch, finally, and Multi-Catch 5.3 Resource Management: try-with-resources and AutoCloseable 5.4 Custom Exceptions and Best Practices 5.5 Java Annotations: Built-in, Meta-Annotations, and Custom Types
6 Chapter 6: Generics and the Collections Framework
6.1 Generics Fundamentals and Generic Methods 6.2 Wildcards, Type Bounds, and Type Erasure 6.3 Core Collections: Lists, Sets, Queues, and Maps 6.4 Sequenced Collections in Java 21 6.5 Sorting, Comparable, and Comparator 6.6 Arrays: Creation, Multidimensional Forms, and the Arrays Utility Class
7 Chapter 7: Functional Programming & Lambda Expressions
7.1 Built-in Functional Interfaces in java.util.function 7.2 Lambda Expressions, Variable Scopes, and Effectively Final 7.3 Method References: Four Varieties and Edge Cases 7.4 Working with java.util.Optional
8 Chapter 8: The Stream API and Data Pipelines
8.1 Stream Creation and Intermediate Operations 8.2 Terminal Operations and Reductions 8.3 Advanced Collectors, Grouping, Partitioning, and Teeing 8.4 Primitive Streams and Parallel Stream Processing
9 Chapter 9: Concurrency, Multithreading, and Virtual Threads
9.1 Thread Fundamentals, Creation, and Lifecycle 9.2 Thread Safety, Synchronization, and the Java Memory Model 9.3 Concurrency Utilities: ExecutorService, Callable, and Future 9.4 Concurrent Collections, Atomics, and Explicit Locks 9.5 Virtual Threads in Java 21 (Carrier Threads, Pinning, and Best Practices)
10 Chapter 10: The Java Platform Module System (JPMS)
10.1 Module Architecture and module-info.java Declarations 10.2 Module Directives: requires, exports, opens, provides, and uses 10.3 Modular Compilation, Packaging, and CLI Execution 10.4 Module Types, Migration Strategies, ServiceLoader SPI, and JLink
11 Chapter 11: Java I/O, NIO.2, and Object Serialization
11.1 Classic Java I/O Streams and Readers/Writers 11.2 Java NIO.2 File API: Path, Paths, and File System Operations 11.3 Advanced NIO.2 Stream Operations and Directory Traversal 11.4 Java Object Serialization and Record Serialization
12 Chapter 12: Implementing Localization and Internationalization
12.1 Locales and Resource Bundles 12.2 Formatting and Parsing Numbers, Currencies, Dates, Times, and Messages
10.2 Module Directives: requires, exports, opens, provides, and uses
Key Takeaways Explain This Topic AI
The requires directive establishes direct module readability, while requires transitive grants implied readability, automatically propagating module access to downstream consumers.
The requires static directive declares a mandatory compile-time dependency that becomes optional at runtime, enabling optional feature sets without runtime ClassNotFoundException failures.
The exports directive makes public types in a package accessible at compile-time and runtime, and qualified exports (exports ... to) restrict this accessibility exclusively to named target modules.
Exporting a package is non-recursive: exporting com.app does not export subpackages like com.app.model, and wildcard export syntax is strictly illegal.
The opens directive enables deep reflective access to private members of a package at runtime without exposing public types at compile-time, while uses and provides with configure decoupled ServiceLoader service provider bindings.
Last updated: September 2026
Module Directives: requires, exports, opens, provides, and uses
A module descriptor ( module-info.java ) controls access boundaries, dependencies, and service bindings through explicit module directives . On the 1Z0-830 exam, questions test the precise differences between module targets versus package targets, implied readability mechanics ( requires transitive ), optional compile-time dependencies ( requires static ), qualified visibility, non-recursive export rules, and reflective permissions.
1. Dependency Directives: requires , requires transitive , and requires static
To consume types declared in another module, a module must declare readability using the requires family of directives.
- 1. Basic requires (Direct Readability) module com.app.billing {
- requires java.sql; // Target is a MODULE name
- requires com.app.inventory; // Target is a MODULE name
- }
- Syntax : requires <module-name>;
Rule : The target must be a module name , never a package name or class name. Writing requires java.sql.DriverManager; or requires java.util; results in a compile-time error .
Readability : Grants the declaring module the ability to read and access exported public types from <module-name> .
Acyclicity : JPMS strictly prohibits cyclic dependencies. If module A requires B; and module B requires A; , both compilation ( javac ) and runtime startup ( java ) fail with a cyclic dependency error.
2. requires transitive (Implied Readability)
Implied readability allows a module to pass along its dependency to any downstream module that reads it. // Module: com.app.repository
- module com.app.repository {
- requires transitive java.sql; // Downstream consumers gain readability to java.sql
- exports com.app.repository.api;
- }
- // Module: com.app.web
- module com.app.web {
requires com.app.repository; // Implicitly gains readability to java.sql!
}
Semantics : If Module X declares requires transitive Y; , and Module Z declares requires X; , then Module Z automatically gains readability to Module Y without needing to write requires Y; in its own descriptor.
Mandatory Use Case (API Leakage) : When an exported class in Module X exposes a type from Module Y in its public or protected method signatures (return types, parameter types, field types, or exceptions), Module X must declare requires transitive Y; . Without transitive , downstream consumers calling that method cannot compile because they cannot resolve the returned type. package com.app.repository.api;
import java.sql.Connection; // From java.sql module
public class DatabaseHelper {
// Public method returns java.sql.Connection!
- // com.app.repository MUST declare 'requires transitive java.sql;'
- public Connection getActiveConnection() {
- return null;
- }
- }
- 3. requires static (Compile-Time Optional Dependency) module com.app.analytics {
- requires static lombok; // Needed during compilation only
- requires static com.optional.profiler; // Optional at runtime
- }
Semantics : The dependency is mandatory during compilation ( javac ), but optional at runtime ( java ).
If the required module is absent on the module path when launching the JVM, the runtime resolves the module graph cleanly without errors.
If the application executes code at runtime that attempts to load classes from the missing module, a NoClassDefFoundError or ClassNotFoundException is thrown. Code should defensively check for class availability before invocation (e.g., via Class.forName() or try-catch ).
Modifiers Combination : You can combine modifiers: requires static transitive <module-name>; or requires transitive static <module-name>; .
- 2. Encapsulation Directives: exports and Qualified exports ... to
- Standard exports module com.app.finance {
- exports com.app.finance.services; // Target is a PACKAGE name
- exports com.app.finance.dto;
- }
- Syntax : exports <package-name>;
Rule : The target must be a package name , never a module or class name.
Accessibility : Exposes all public and protected classes, interfaces, records, and enums in <package-name> to any module that reads com.app.finance .
No Subpackage Inheritance : Exporting a package does not export its subpackages. For example, exports com.app.finance; does not export com.app.finance.services or com.app.finance.internal . Every subpackage must have its own exports directive.
No Wildcards : Wildcard syntax like exports com.app.finance.*; is strictly forbidden by the Java compiler.
Internal Encapsulation : Non-public members, package-private classes, and all types inside non-exported packages remain strictly inaccessible outside the module.
- Qualified Exports ( exports ... to ) module com.app.core {
- // Only com.app.admin and com.app.billing can access com.app.core.internal
- exports com.app.core.internal to com.app.admin, com.app.billing;
- }
Restricts package accessibility strictly to the specified comma-separated list of target module names .
Any module not in the to list cannot access the package at compile time or runtime.
3. Reflection Directives: opens and Qualified opens ... to
Frameworks relying on reflection (e.g., ORMs, JSON serializers, dependency injectors) often need access to private fields and constructors without exposing those internal implementation details as a public compile-time API. module com.app.model {
exports com.app.model.api; // Accessible at compile time and runtime
opens com.app.model.entities; // Runtime reflection only!
- opens com.app.model.dto to com.fasterxml.jackson.databind; // Qualified opens
- }
- Syntax : opens <package-name>; or opens <package-name> to <module-name-1>, <module-name-2>;
Target : Must be a package name (with target module names in the to clause for qualified opens).
Compile-Time Isolation : Code in other modules cannot compile against classes in opened-only packages. javac treats unopened and opened-only packages as hidden.
Runtime Reflection : Allows other modules (or specified modules in qualified opens) to perform deep reflection ( AccessibleObject.setAccessible(true) ) on private , protected , and package-private elements within <package-name> .
Open Module Constraint : You cannot use opens inside an open module (causes a compile error).
4. Service Directives: uses and provides ... with
JPMS integrates directly with java.util.ServiceLoader to support decoupled Service Provider Interfaces (SPI) . // Service Consumer Module Descriptor
- module com.app.client {
- requires com.app.spi; // Module containing the interface
- uses com.app.spi.PaymentGateway; // Target is fully qualified INTERFACE/CLASS
- }
- // Service Provider Module Descriptor
- module com.app.stripe.provider {
- requires com.app.spi;
- provides com.app.spi.PaymentGateway
- with com.app.stripe.StripePaymentGateway; // Target is SPI and Implementation
- }
uses <interface-or-class-name>; :
Informs the runtime that the declaring module consumes implementations of the specified interface or abstract class via ServiceLoader.load() .
The target must be a fully qualified type name , not a module or package.
provides <interface-name> with <implementation-class-1>, <implementation-class-2>; :
Informs the runtime that this module supplies one or more concrete implementations for the service interface.
Multiple implementations are separated by commas.
The implementation class does not need to be exported in an exports directive.
5. Directives Master Reference & Exam Trap Matrix
- Directive Target Entity Valid Target Type Compile-Time Visibility Runtime Deep Reflection
- requires M; Module Module name Exported types of M Only if opened by M
- requires transitive M; Module Module name Exported types of M + passes to consumers Only if opened by M
- requires static M; Module Module name Exported types of M (Mandatory) Optional at runtime
- exports P; Package Package name public / protected types to all Public types only
exports P to M1, M2; Package Package name ( to Modules) public / protected types to M1, M2 Public types to M1, M2
- opens P; Package Package name None (Hidden from javac ) All members (including private)
- opens P to M1; Package Package name ( to Module) None (Hidden from javac ) All members to M1 only
- uses S; Type Interface or Class name N/A (Service Consumer) Via ServiceLoader
- provides S with C; Types Interface with Concrete Class N/A (Service Provider) Instantiated by ServiceLoader