OCP 17 Exam - chapter 12 notes - modules
Note: Java Platform Module System was introduced in JDK 9 in project Jigsaw. In Java 25 modules would be available through imports like regular classes.
Running and packaging simple module
Folder structure of app
:
1
2
3
4
- app
- src/pkg
- App.java // prints hello world
- module-info.java // only module app { }
Package names must be unique: e.g. I cannot add class in package “java.util” as already exists in module “java.base”.
error: duplicate module on application module path module in products
Run below commands in parent directory https://github.com/RG9/rg-playground-ocp17/blob/main/java-modules-demo.
Compile to app/out
:
1
$ javac --module-path mods -d app/out app/src/pkg/*.java app/module-info.java
Note: –module-path is not needed now as “app” module do not have any dependencies, but good to know that parameter
Package into jar:
1
2
3
4
5
$ jar -cvf mods/app.jar -C app/out .
added manifest
added module-info: module-info.class
adding: pkg/(in = 0) (out= 0)(stored 0%)
adding: pkg/App.class(in = 414) (out= 289)(deflated 30%)
Run:
1
2
$ java -p mods -m app/pkg.App
Hello app!
-p
is abbreviation of--module-path
,-m
is abbreviation of--module
Be aware of format of
--module
param, which should be separated by slash:-m module/class
Note: we don’t have to export any package to be able to run class with main method.
Side note: Java module system is different than one in Intellij! See 1 and 2. Instead of creating a project, you should just “Open” parent directory.
Simple dependency on other module with “requires” and automatic module
- if we want to export all packages and we don’t require any module, then there is no need to define
module-info.java
“automatic module” is jar on module path that does not have
module-info.java
and exports all packages
automatic module name will be extracted from jar name, e.g.
products-0.1-SNAPSHOT.jar
becomesproducts
modulein app’s
module-info.java
addrequires products;
and build again
ServiceLoader that “uses” SPI and Service Provider that “provides-SPI-with-IMPL”
Let’s say we want to display products (SPI - Service Provider Interface) from many different suppliers/manufactures (provider/impl). We can load products as service to avoid building the whole application when new supplier will be added.
- in app code load
Products
SPI viaServiceLoader
(note: no need to rebuildproducts
module):1 2 3 4 5
private static Products getProductsInstance() { return ServiceLoader.load(Products.class) .findFirst() .orElseGet(() -> getDefaultProductsInstance()); }
note:
ServiceLoader#load
returnsServiceLoader
which isIterable
, so provides other methods likestream()
,forEach()
- in app’s
module-info.java
adduses products.Products;
w/o
uses
we cannot compileServiceLoader
: java.util.ServiceConfigurationError: products.Products: module app does not declareuses
`
another keyword is
opens
that allows reflection
Remember to end every statement with
;
inmodule-info.java
OK, this was service loader/client part, next add service provider that will provide implementation.
- let’s define module
products.pl
with class:1 2 3 4 5 6 7 8 9 10
public class PolishProducts implements Products { @Override public List<Products.Product> findAll() { return List.of( () -> "Pierogi", () -> "Żubrówka" ); } }
- in
module-info.java
needs to do 2 things:requires products;
as we depend on the SPI interfaceprovides products.Products with pl.products.PolishProducts;
- declare thatProducts
SPI will be provided withPolishProducts
implementation
Migration strategies
- Top down: add all JARs to module path as “automatic” modules, then migrate one module at a time to be “named” module.
- Bottom up: all unmigrated “unnamed” modules stays on class path. Pick next module with the least dependencies and migrate it.
unnamed module is not visible to other modules on the module path, because module on module path cannot refer to classpath.
Tricky review questions
An unnamed module doesn’t use a module-info.java file.
module was defined with keyword class!! “class dragon {“
No modules need to specify requires on the service provider since that is the implementation.
Playground code
https://github.com/RG9/rg-playground-ocp17/blob/main/java-modules-demo
Credit: OCP Oracle Certified Professional Java SE 17 Developer Study Guide