-
Notifications
You must be signed in to change notification settings - Fork 2k
Support JPMS for Spring Cloud Azure Libraries
- What is JPMS
- What is a module
- How to create a Java module
- Useful tools
- How to make a Spring Cloud Azure library a module
- References
JPMS is Java Platform Module System.
Until Java 9, Java's top-level code organization element had been the package. Starting with Java 9 that changed: above the package now is the module. The module collects related packages together.
The JPMS is a code-level structure, so it doesn't change the fact that we package Java into JAR files.
Modularity adds a higher level of aggregation above packages. The key new language element is the module - a uniquely named, reusable group of related packages, as well as resources (such as images and XML files) and a module descriptor specifying
- the module's name
- the module's dependencies (that is, other modules this module depends on)
- the package it explicitly makes available to other modules (all other packages in the modules are implicitly unavailable to other modules)
- the services it offers
- the services it consumes
- to what other modules it allows reflection
As mentioned, a module must provide a module descriptor. A mdodule descriptor is defined in a file named module-info.java
.
One can refer to the module-info.java
of azure-cosmos for example.
Here are some commonly used module directives:
-
requires: A requires module directive specifies that this module depends on another module—this relationship is called a module dependency. Each module must explicitly state its dependencies. When module A requires module B, module A is said to read module B and module B is read by module A. To specify a dependency on another module, use requires
-
requires transitive: To specify a dependency on another module and to ensure that other modules reading your module also read that dependency—known as implied readability—use requires transitive
-
requires static: represents the concept of optional dependence such a module is mandatory at compilation and optional at runtime.
-
exports and exports…to: An exports module directive specifies one of the module’s packages whose public types (and their nested public and protected types) should be accessible to code in all other modules. An exports…to directive enables you to specify in a comma-separated list precisely which module’s or modules’ code can access the exported package—this is known as a qualified export.
More syntax about module-info.java can see https://www.oracle.com/corporate/features/understanding-java-9-modules.html.
If a project, which is modular itself but has a dependency which is not a module yet, how will the JPMS handle that?
It automatically creates a module:
-
Name:
- If the JAR defines the
Automatic-Module-Name
header in the manifest file, it will be the module's name. - Otherwise the JAR name is the module's name.
- If the JAR defines the
-
Requires:
- An automatic module read all other modules.
-
Exports/Opens
- An automatic module exports all packages and also opens them for deep reflection.
To list the JDK's set of modules, which includes the standard modules that implement the Java Language SE Specification (names starting with java), JavaFX modules (names starting with JavaFX), JDK-specific modules (names starting with jdk).
A version string follows each module name - @9
indicates that the module belongs to Java 9.
java --list-modules
This command can be used to verify whether a module is valid.
java -p ~/.m2/repository/com/azure/azure-core/1.32.0/azure-core-1.32.0.jar --list-modules
Our current plan is the same as the Spring's team, they don't support full JPMS yet. https://github.com/spring-projects/spring-framework/issues/18079.
So we only need to provide Automatic Module Name
for a Spring Cloud Azure library.
Check this for example https://github.com/Azure/azure-sdk-for-java/blob/d96d0333112997b0ee5aa03aacfad2d0b0e7d1d4/sdk/spring/spring-cloud-azure-starter/pom.xml#L106-L115.
But if you are developing a SDK level library, we should add the module-info.java
module descriptor for it. For example azure-identity-providers-*
libraries.
Check this for example https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/identity/azure-identity/src/main/java/module-info.java.
- Create a new application with java version greater than 9, for example Java 11.
- Add a
module-info.java
file for this application - Add the module name you want to test in the file, such as
requires com.azure.identity.providers.mysql
- Then run the application, if successful proves OK or you need to check again.
BTW, if you do not use codes from the tested module, this test method won't work.
- https://www.oracle.com/corporate/features/understanding-java-9-modules.html
- https://stackoverflow.com/questions/46741907/what-is-an-automatic-module#:~:text=The%20module%20name%20of%20an,JAR%20file%20by%20the%20ModuleFinder%20.
- https://github.com/tfesenko/Java-Modules-JPMS-CheatSheet/blob/master/README.md
- Spring Credential
- Spring Cloud Azure 4.0 Design
- Spring Cloud Azure AutoConfigure Design
- Spring Cloud Azure Core Design
- Spring Cloud Azure Messaging Design
- Spring Cloud Azure Service Bus Spring Jms Support Design
- Design for directory, module name and package path for Spring Cloud Azure messaging
- Design for Remove warning logs of unknown configs for Kafka Passwordless
- Design for Enhance AAD token authentication converter to customized granted authorities converter
- Design for Enhance the ObjectMapper to support Spring Boot's pattern to enable autoconfiguration
- Passwordless connection support for Spring Cloud Azure
- Passwordless connection support for MySQL
- Passwordless connection support for Event Hubs Kafka
- Remove warning logs of unknown configs for Kafka Passwordless