Modules
Copyright © Seán Kennedy
Modules
Java 11 (1Z0-819)
Copyright © Seán Kennedy
Modules
• Modules, introduced in Java 9, provide an extra layer of
encapsulation by enabling us to group related packages.
• From a high-level, modules enable us to specify well-
defined boundaries/dependencies in our code base.
• As a developer, you can specify which packages are
accessible outside the module and also the module
dependencies (the other modules that the module itself
depends upon).
Copyright © Seán Kennedy
Why Modules?
• Improved access control:
• in addition to private, package-private, protected and public
now we have the ability to restrict packages to certain other
packages.
• Improved large-scale structure of applications:
• boundaries/dependencies in your code base.
• hide implementation details.
• improved decoupling.
Copyright © Seán Kennedy
Why Modules?
• Reduced build sizes:
• as Java itself is now modularised, developers can specify
which of the Java API modules are required for their custom
applications; this results in smaller application sizes (a
consideration for memory-constrained devices).
• Earlier detection of missing code:
• prior to modules, missing classes/JAR files might only be
realised at runtime, when the class/JAR file was being used
for the first time.
• as modules specify their dependencies - in a fully modular
environment, the Java VM can check the whole dependency
graph when it starts up; thus, any missing modules would be
spotted much earlier. 5
Copyright © Seán Kennedy
Modular Application
Farm Application
[Link] Modules
[Link] [Link]
[Link] [Link]
Copyright © Seán Kennedy
Structure of a Module
[Link] Module
farm [Link] [Link] Packages
[Link]
[Link]
[Link]
Copyright © Seán Kennedy
Modules
• By default, all classes in the packages in a module are
strongly encapsulated i.e. no other module can use these
classes, even if they are public classes.
• Package names and module names live in separate
namespaces i.e. you can have the same identifiers without
any conflict (name clash).
• A module contains one or more packages plus a
[Link] file.
Copyright © Seán Kennedy
Modules
• When compiling a module, it is more convenient to use
“module directories” as otherwise we would have to list all
the .java source files (including [Link]).
• If you use a module directory, then the name of the module
directory must match the name of the module in the
[Link] file.
• Place the [Link] file in the root of the source tree
of the module you are describing.
Copyright © Seán Kennedy
Copyright © Seán Kennedy
javac (compiler) flags
Listing all the source files: javac –d {dir} {all the java source files, including [Link]}
Module directory(ies): javac –d {dir} –m {module_name}, {module_name} --module-source-path {src_dir}
Dependencies to other --module-path or –p
custom (possibly 3rd party)
modules:
Examples: javac -d out src/com/farm/[Link] src/[Link]
javac -d out -m TestModuleFarm --module-source-path src
javac -d out --module TestModuleFarm --module-source-path src
javac –d {dir} –m {module_name} --module-source-path {src_dir} –p {dir e.g. “mods”}
Short Version Long Version
-m --module
-p --module-path
11
Copyright © Seán Kennedy
java flags
java –p {module_path} –m {module}/{fully qualified main class}
Example: java -p out -m TestModuleFarm/[Link]
Example: java --module-path out --module TestModuleFarm/[Link]
Short Version Long Version Comment
-m --module -
-p --module-path The “classpath” for modules.
12
Copyright © Seán Kennedy
Flags Recap
Command Flags Question flags answer
javac -d {dir} where to put the class files?
-m {module_name} what is the name of the module?
--module {module_name}
--module-source-path {src_dir} where is the module source code?
-p {dir e.g. “mods”} where are the custom modules we need (if any) ?
--module-path {dir e.g. “mods”}
Example: javac -d out -m TestModuleFarm --module-source-path src
java -p {module_path} where is the module?
--module-path {module_path}
-m {module}/{fully qualified main class} what is the name of the module?
--module {module}/{fully qualified main class}
Example: java -p out -m TestModuleFarm/[Link]
13
Copyright © Seán Kennedy
TestModuleFarm
Listing all source files
Copyright © Seán Kennedy
TestModuleFarm2
Module Directory
Copyright © Seán Kennedy
Dependencies between Modules
• As stated earlier, by default, all classes in the packages in a
module are strongly encapsulated i.e. no other module can
use these classes, even if they are public classes.
• If you want a package to be visible outside the module then
“export” it in the [Link] file. The keyword exports
is used.
• If a module “depends” on another module, the keyword
requires is used.
16
Copyright © Seán Kennedy
Dependencies between Modules
• All modules implicitly depend on the [Link] module.
• the module exports the [Link] package (String, Object)
• Remember:
• you export (exports) a package
• you depend (requires) on a module
• The requires keyword between modules forms a dependency
graph.
17
Copyright © Seán Kennedy
Dependencies between Modules
[Link] [Link]
Copyright © Seán Kennedy
1. Run SellThem example.
2. Jar version.
Copyright © Seán Kennedy
opens
• Frameworks such as Spring and Hibernate, frequently
require access to our code at runtime via “reflection”.
• [Link](“[Link]”).newInstance();
• Via reflection, calling code can override access control and
as a result of this power, you must clearly state that you allow
this type of access.
• Thus we want our types to be strongly encapsulated at
compile-time but provide runtime access via reflection.
The keyword opens provides this.
20
Copyright © Seán Kennedy
opens
• In your [Link] file you state:
• opens packageName;
• opens packageName to moduleName;
• A module itself can be open. This automatically opens all
packages inside the module.
21
Copyright © Seán Kennedy
requires
[Link] [Link]
[Link]
22
Copyright © Seán Kennedy
requires transitive
[Link] [Link]
[Link]
Note: The following is an error:
23
Copyright © Seán Kennedy
Operations on a Module
• Packaging a module
• creating and executing a modular JAR (Java ARchives).
• Describing a module (java and jar).
• jdeps – discovering the dependencies in the module.
• jmod
• native libraries
• not executable
• intended for use with the jlink tool to build a custom native
image.
24
Copyright © Seán Kennedy
Services
• Modules are tightly coupled due to the use of requires,
exports and the knowledge and creation of specific types.
• Services enable the decoupling of modules.
• Rather than modules directly coupling to other modules,
there is now a middle layer, the service registry which
abstracts the consumers from the producers.
• The service (interface) contract, which is hosted by the
registry, is what binds the consumers and producers together.
25
Copyright © Seán Kennedy
[Link]
[Link]
[Link]
26
Copyright © Seán Kennedy
[Link] [Link]
[Link]
[Link] farm.hired_hand
[Link]
farm.family_member
27
Copyright © Seán Kennedy
[Link]
provides
[Link]
[Link]
uses Registry provides
Service Contract
[Link]
Copyright © Seán Kennedy
OwnerService example
Copyright © Seán Kennedy
[Link]
[Link]
[Link]
Registry
[Link]
Service Contract
[Link]
[Link]
Copyright © Seán Kennedy
Types of Modules
• There are 3 types of modules:
• Named modules – contain a module-info file and appear on the
module path, not the classpath i.e. --module-path as opposed
to --class-path.
• Unnamed modules – non-modular JAR’s i.e. no module-info
file (if present, it is ignored) and appear on the classpath.
• think pre-modules i.e. the way Java worked before modules were
introduced.
• classpath code can read module path code but not vice vearsa.
• Automatic modules – non-modular JAR’s (typically from a
3rd party) that are on the module path
• Java automatically creates named modules for them by either:
• Automatic-Module-Name property in [Link]
• otherwise, a set of naming rules are applied
31
Copyright © Seán Kennedy
Automatic Modules
• Required when a modular application encounters a
non-modular JAR on the module path.
• Rules for naming them:
• Automatic-Module-Name property in [Link]
• otherwise, the following rules apply (e.g. [Link]):
• extension is dropped (text-utils-1.0)
• version information at end of file is dropped (text-utils)
• replace characters (other than letters/numbers) with dots
([Link])
• replace any sequence of dots with single dots
• remove single dots from beginning and end
32
Copyright © Seán Kennedy
Automatic Modules
• All the packages in the automatic module are exported.
• The modular application (which is using the automatic
module), will need to state that it requires the automatic
module in its module-info file. This is why the naming rules
are important.
33
Copyright © Seán Kennedy
Migration Strategies
• What if you want to migrate your classpath-based applications
to modules?
• There are 2 strategies that you can follow:
• Bottom-up
• Top-down
Bottom-up Top-down
[Link]
[Link] [Link]
[Link] [Link]
34
Copyright © Seán Kennedy
Bottom-up
• Turning JAR files on the classpath into modules that we can
put on the module path.
• Algorithm:
1. Start at the “leaf” nodes i.e. nodes that have no dependencies
other than the JDK.
2. Create a [Link] file for the JAR. Name the module.
Ensure all packages required by other (higher-level) JAR’s are
exported using the exports directive. In addition, all modules this
JAR depends upon must have requires directives.
3. Once migrated, this newly named module moves from the
classpath to the module path.
4. Repeat with the next lowest JAR until you finally have
modularised the top level JAR i.e. you are done.
35
Copyright © Seán Kennedy
Bottom-up – using jdeps
• jdeps can be used to automatically generate the
[Link] file
• So, rather than having to analyse all the code to check for all
dependencies, jdeps can do that for you.
Careful! All packages will be exported.
36
Copyright © Seán Kennedy
Bottom-up
• The bottom-up approach yields benefits when all the modules
are modularised and the top-level root module is complete.
• An issue arises with the bottom-up approach when there are
external JAR’s that we do not have control over and are not
modularised yet.
• Do we wait for the external JAR developers to migrate the
unnamed modules or do we try to maintain the module
descriptors ourselves? Neither option is ideal.
• Constrained by the weakest link in the set of dependencies.
37
Copyright © Seán Kennedy
Top-down
• Proceeds in a top-down fashion from the root.
• Uses automatic modules - where a modular application
encounters a non-modular JAR file on the module path and a
module is generated for it automatically .
• Thus, we can simply move the unaltered external non-modular
(i.e. unnamed) module/JAR file from the classpath to the module
path; where it will be converted to an automatic module.
• All we need to know is what name Java will give the automatic
module and modify our dependencies (requires) accordingly.
38
Copyright © Seán Kennedy
Top-down
[Link]
unnamed unnamed
[Link] [Link]
classpath
module-path
[Link] [Link]
automatic named
39
Copyright © Seán Kennedy
Modules
Java 11 (1Z0-819)
40
Copyright © Seán Kennedy