Project Jigsaw was developed to modularize the JDK and is implemented with JSR 376: JavaTM Platform Module System in Java 9. The main objectives of Project Jigsaw were as follows:
- Make it easier to construct and maintain Java libraries and large applications for Java SE and Java EE platforms.
- Improve application performance by enabling scaling down of Java SE platform and JDK.
The JSR 376 specification defines a module system for the following requirements of large Java applications:
- Reliable Configuration: One of the problems with the class-path mechanism for making program components available to a Java application is that it does not define the relationships between components, making it difficult to ascertain if all the necessary components have been specified. If a required component is missing, it may not be known and, when the component is made use of or invoked in an application, an error results. With JSR 376, dependency on other components is declared so that all the needed components are available when an application is run. Another issue with the class-path mechanism which is fixed with JSR 376 is that it allows classes in the same package to be loaded from different components, resulting in error.
- Strong Encapsulation: JSR 376 has the provision to let a component declare which of its packages or public types are accessible and which are not. Previously, the access-control mechanism allows access to any internal packages of a component.
JSR 376 provides the following additional benefits:
- Scalability: Modularized custom configurations may be developed that consist of only the minimum required set of components and define minimum required functionality.
- Platform Integrity: The encapsulation provided by the JSR prevents access to the internal APIs of Java libraries, which was not needed to start with but not prevented, either.
- With class dependencies clearly defined, program optimization may be applied.
In two tutorials, we shall introduce modules and discuss creating a Hello module. This first tutorial has the following sections:
- What Is a Module?
- Class-path vs. Module System Class Loading
- Modular Platform Objectives
- Modular Platform Structure or Design
- Exporting Packages
- Declaring Dependency on Other Modules
A module is a named set of Java packages, resources, and native libraries. A module could depend on other module/s, and a module declares which other modules are required to compile and run the code in the packages in the module. A module also declares which of its packages are exported for use by other modules and which are not. A module declaration is made with module, a new keyword in Java SE 9. A module consists of two source files: the module-info.java file for a module declaration, and the main class file for the Main class declaration. The source code for the two files is in a directory by the same name as the module by convention.
Unlike the class-path–based class loading which loads all the classes specified in the class path, the module loads only the code of the required modules. Unlike the class-path–based class loading, the module system does not let packages by the same name cause any interference. Only the packages exported by the modules declared a dependency on are loaded for access.
The objectives of the modular platform or system, as defined in the Java 9 specification, include the capability to provide for varied configurations by dividing the Java SE platform into modules that may be combined at build time, compile time, or run time. A configuration could correspond to the complete Java SE platform, or could consist of a specific set of modules. A configuration could also correspond to one of the Compact Profiles in Java SE 8.
The module system distinguishes between standard modules and non-standard modules. Standard modules have their specification managed by the Java Community Process (JCP) and have module names starting with “java.”. Non-standard modules must not have their names start with “java.”. At the base of the module structure is the module java.base, which contains essential classes, such as java.lang.Object and java.lang.String. At the top of the module structure is the java.se.ee module, an aggregator module, which contains all the modules of the Java SE Platform.
By default, all packages in a module are exported. A module optionally exports specific public types in its packages with the exports directive. A module declaration may contain multiple exports directives and each exports directive must declare only one package. An exports directive provides other modules access at compile and run time to public and protected types in the package and the public and protected members of those types. A non-standard module must not export any standard API packages.
A module may depend on other modules. Dependency on another module is declared with the requires directive in the module declaration. The requiresdirective introduces three new concepts:
- Reliable configuration
As an example, if module A requires module B, it provides reliable configuration for the presence of B. It allows A to read B; this is called readability. It allows code in A to access code B; this is called accessibility.
Implicitly declared dependence on a module is declared with the requires transitive directive. Any module that requires (with requires) a module that contains a requires transitive directive also implicitly requires the module declared in the requires transitive directive. The requires transitive directive introduces implied readability. A standard module may depend on a non-standard module, as declared with a requires directive, but it must not grant implied readability to a non-standard module as declared with requires transitive. A non-standard module may grant implied readability to a standard module.
We have introduced modules in Java 9. We used some new terms for which the Java 9 specification has added new keywords; these include module, exports, requires, and transitive.
Having introduced modules, in a subsequent tutorial we shall discuss creating a Hello module.