Chapter 11 Modules Flashcards

Understanding Modules * Describe the Modular JDK * Declare modules and enable access between modules * Describe how a modular project is compiled and run

1
Q

Introducing Modules

A
  • The Java Platform Module System (JPMS) was introduced in Java 9
  • The main purpose of a module is to provide groups of related packages to offer a particular set of functionality to developers.

The Java Platform Module System includes the following:

  • A format for module JAR files
  • Partitioning of the JDK into modules
  • Additional command-line options for Java tools

A module is a group of one or more packages plus a special file called module-info.java.

dependencies where one module relies on code in another.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Java Platform Module System (JPMS)

A
  • The Java Platform Module System (JPMS) was introduced in Java 9
  • The Java Platform Module System includes the following:
    • A format for module JAR files
    • Partitioning of the JDK into modules
    • Additional command-line options for Java tools
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

BENEFITS OF MODULES

A
  • Better Access Control
    • fifth level of access control.
    • They can expose packages within the modular JAR to specific other packages.
    • This stronger form of encapsulation really does create internal packages.
  • Clearer Dependency Management
    specify their dependencies in the module-info.java file.
  • Custom Java Builds
    • allows developers to specify what modules they actually need.
    • A tool called jlink is used to create this runtime image.
  • Improved Performance
    improves startup time and requires less memory to run.
  • Unique Package Enforcement
    A package is only allowed to be supplied by one module.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

module-info.java

A

This is the simplest possible module-info.java file

module zoo.animal.feeding {
}
  • The module-info file must be in the root directory of your module.
  • The module-info file must use the keyword module.
1: module zoo.animal.care {
2: exports zoo.animal.care.medical;
3: requires zoo.animal.feeding;
4: }
  • Line 1 specifies the name of the module.
  • Line 2 lists the package we are exporting so it can be used by other modules.
  • On line 3, we see a new keyword. The requires statement specifies that a module is needed. The zoo.animal.care module depends on the zoo.animal.feeding module.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

There are a few key differences between a module-info file and a regular Java class:

A
  • The module-info file must be in the root directory of your module. Regular Java classes should be in packages.
  • The module-info file must use the keyword module instead of class, interface, or enum.
  • The module name follows the naming rules for package names. It often includes periods (.) in its name. Regular class and package names are not allowed to have dashes (-). Module names follow the same rule.

That’s a lot of rules for the simplest possible file. There will be many more rules when we flesh out this file later in the chapter.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

CAN A MODULE-INFO.JAVA FILE BE EMPTY?

A

Yes. As a bit of trivia,

it was legal to compile any empty file with a .java extension even before modules.

The compiler sees there isn’t a class in there and exits without creating a .class file.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

COMPILING OUR FIRST MODULE

A

> [!NOTE]
When you’re entering commands at the command line, they should be typed all on one line.

javac --module-path mods -d feeding feeding/zoo/animal/feeding/*.java feeding/module-info.java
  • the -d option specifies the directory to place the class files in.
  • The end of the command is a list of the .java files to compile. You can list the files individually or use a wildcard for all .java files in a subdirectory.
  • --module-path option indicates the location of any custom module files.
  • The syntax --module-path and -p are equivalent.

The following four commands show the -p option:

javac -p mods -d feeding feeding/zoo/animal/feeding/*.java feeding/*.java

javac -p mods -d feeding feeding/zoo/animal/feeding/*.java feeding/module-info.java

javac -p mods -d feeding feeding/zoo/animal/feeding/Task.java feeding/module-info.java

javac -p mods -d feeding feeding/zoo/animal/feeding/Task.java feeding/*.java
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

WHAT HAPPENED TO THE CLASSPATH?

A

You can still use these options in Java 11. In fact, it is common to do so when writing nonmodular programs.

-cp, --class-path, and -classpath

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

RUNNING OUR FIRST MODULE

A

Pay special attention to the book.module/com.sybex.OCP part. It is important to remember that you specify the module name followed by a slash (/) followed by the fully qualified class name.

java --module-path mods --module book.module/com.sybex.OCP
  1. Location of modules, --module-path, -p
  2. Module name, --module, -m
  3. Module/package separator
  4. Package name
  5. Class name

examples:

java --module-path feeding --module zoo.animal.feeding/zoo.animal.feeding.Task

java -p feeding -m zoo.animal.feeding/zoo.animal.feeding.Task
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

PACKAGING OUR FIRST MODULE

A

Be sure to create a mods directory before running this command:

jar -cvf mods/zoo.animal.feeding.jar -C feeding/ .

  • We are packaging everything under the feeding directory
  • and storing it in a JAR file named zoo.animal.feeding.jar under the mods folder.

run the program again, but this time using the mods directory instead of the loose classes:

java -p mods -m zoo.animal.feeding/zoo.animal.feeding.Task

Since the module path is used, a module JAR is being run.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

> [!NOTE]
It is possible to version your module using the –module-version option.
This isn’t on the exam but is good to do when you are ready to share your module with others.

A

version your module using the –module-version option.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

ORDER MATTERS!

A

Order matters when compiling a module.

javac -p mods -d care care/module-info.java care/zoo/animal/care/details/*.java care/zoo/animal/care/medical/*.java

The compiler complains that it doesn’t know anything about the package zoo.animal.care.medical.

care/module-info.java:3: error: package is empty or does not exist:
zoo.animal.care.medical
exports zoo.animal.care.medical;
  • A package must have at least one class in it in order to be exported.
  • Since we haven’t yet compiled zoo.animal.care.medical.Diet, the compiler acts as if it doesn’t exist.
  • If you get this error message, you can reorder the javac statement.
  • Alternatively, you can compile the packages in a separate javac command, before compiling the module-info file.

jar -cvf mods/zoo.animal.care.jar -C care/ .

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Diving into the module-info File

A

These are not Java keywords they are directives, can appear in any order in the module-info file.

  • exports,
  • requires,
  • provides,
  • uses,
  • and opens.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

EXPORTS

A
  • exports packageName exports a package to other modules.
  • It’s also possible to export a package to a specific module.
module zoo.animal.talks {
exports zoo.animal.talks.content to zoo.staff;
exports zoo.animal.talks.media;
exports zoo.animal.talks.schedule;
requires zoo.animal.feeding;
requires zoo.animal.care;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

EXPORTED TYPES

A

Exporting a package

  • All public classes, interfaces, and enums are exported.
  • Further, any public and protected fields and methods in those files are visible.
  • Fields and methods that are private are not visible because they are not accessible outside the class.
  • Similarly, package-private fields and methods are not visible because they are not accessible outside the package.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

REQUIRES TRANSITIVE

A

requires moduleName specifies that the current module depends on moduleName.

There’s also a requires transitive moduleName, which means that any module that requires this module will also depend on moduleName.

module zoo.animal.feeding {
exports zoo.animal.feeding;
}

module zoo.animal.care {
exports zoo.animal.care.medical;
requires transitive zoo.animal.feeding;
}

module zoo.animal.talks {
exports zoo.animal.talks.content to zoo.staff;
exports zoo.animal.talks.media;
exports zoo.animal.talks.schedule;
// no longer needed requires zoo.animal.feeding;
// no longer needed requires zoo.animal.care;
requires transitive zoo.animal.care;
}

module zoo.staff {
// no longer needed requires zoo.animal.feeding;
// no longer needed requires zoo.animal.care;
requires zoo.animal.talks;
}
17
Q

Duplicate requires Statements

module bad.module {
requires zoo.animal.talks;
requires transitive zoo.animal.talks;
}
A

Java doesn’t allow you to repeat the same module in a requires clause. It is redundant and most like an error in coding. Keep in mind that requires transitive is like requires plus some extra behavior.

18
Q

PROVIDES, USES, AND OPENS

A

The provides keyword specifies that a class provides an implementation of a service.
To use it, you supply the API and class name that implements the API:

provides zoo.staff.ZooApi with zoo.staff.ZooImpl

The uses keyword specifies that a module is relying on a service. To code it, you supply the API you want to call:

uses zoo.staff.ZooApi
19
Q

Discovering Modules

A
  • “unjar” module JAR file and open the module-info file.
  • java command, -d or –describe-module
java -p mods -d zoo.animal.feeding

java -p mods --describe-module zoo.animal.feeding
  • jar command, -d or –describe-module
jar -f mods/zoo.animal.feeding.jar -d

jar --file mods/zoo.animal.feeding.jar --describe-module
20
Q

Discovering Modules via java command
module-info in zoo.animal.feeding:

module zoo.animal.feeding {
exports zoo.animal.feeding;
}
A

The java command now has an option to describe a module. The following two commands are equivalent:

java -p mods -d zoo.animal.feeding

java -p mods --describe-module zoo.animal.feeding

Each prints information about the module. For example, it might print this:

zoo.animal.feeding file:///absolutePath/mods/zoo.animal.feeding.jar
exports zoo.animal.feeding
requires java.base mandated
  • The first line is the module we asked about:** zoo.animal.feeding**.
  • The second line starts information about the module. In our case, it is the same package exports statement we had in the module-info file.
  • On the third line, we see requires java.base mandated. Now wait a minute. The module-info file very clearly does not specify any modules that zoo.animal.feeding has as dependencies.
  • The java.base module is special. It is automatically added as a dependency to all modules. This module has frequently used packages like java.util. That’s what the mandated is about. You get java.base whether you asked for it or not.
  • In classes, the java.lang package is automatically imported whether you type it or not. The java.base module works the same way. It is automatically available to all other modules.
21
Q

MORE ABOUT DESCRIBING MODULES

module-info in zoo.animal.care:

module zoo.animal.care {
exports zoo.animal.care.medical to zoo.staff;
requires transitive zoo.animal.feeding;
}
A

Now we have the command to describe the module and the output.

java -p mods -d zoo.animal.care

zoo.animal.care file:///absolutePath/mods/zoo.animal.care.jar
requires zoo.animal.feeding transitive
requires java.base mandated
qualified exports zoo.animal.care.medical to zoo.staff
contains zoo.animal.care.details
  • The first line of the output is the absolute path of the module file.
  • The two requires lines should look familiar as well.
  • The first is in the module-info, and the other is added to all modules.
  • Next comes something new. The qualified exports is the full name of exporting to a specific module.
  • Finally, the contains means that there is a package in the module that is not exported at all. This is true. Our module has two packages, and one is available only to code inside the module.
22
Q

Listing Available Modules

A

you can use the java command to list the modules that are available. The simplest form lists the modules that are part of the JDK:

java --list-modules

When we ran it, the output went on for 70 lines and looked like this:

java.base@11.0.2
java.compiler@11.0.2
java.datatransfer@11.0.2

This is a listing of all the modules that come with Java and their version numbers. You can tell that we were using Java 11.0.2 when testing this example.

java -p mods --list-modules
zoo.animal.care file:///absolutePath/mods/zoo.animal.care.jar
zoo.animal.feeding file:///absolutePath/mods/zoo.animal.feeding.jar
zoo.animal.talks file:///absolutePath/mods/zoo.animal.talks.jar
zoo.staff file:///absolutePath/mods/zoo.staff.jar

Since these are custom modules, we get a location on the file system. If the project had a module version number, it would have both the version number and the file system path.

> [!Note]
that –list-modules exits as soon as it prints the observable modules.
It does not run the program.

23
Q

Showing Module Resolution

A
  • In case listing the modules didn’t give you enough output, you can also use the –show-module-resolution option.
  • You can think of it as a way of debugging modules.
  • It spits out a lot of output when the program starts up.
  • Then it runs the program.
java --show-module-resolution -p feeding -m zoo.animal.feeding/zoo.animal.feeding.Task

Luckily you don’t need to understand this output. That said, having seen it will make it easier to remember. Here’s a snippet of the output:

root zoo.animal.feeding file:///absolutePath/feeding/
java.base binds java.desktop jrt:/java.desktop
java.base binds jdk.jartool jrt:/jdk.jartool
...
jdk.security.auth requires java.naming jrt:/java.naming
jdk.security.auth requires java.security.jgss jrt:/java.security.jgss
...

All fed!
  • It starts out by listing the root module. That’s the one we are running:
    zoo.animal.feeding.
  • Then it lists many lines of packages included by the mandatory java.base module.
  • After a while, it lists modules that have dependencies.
  • Finally, it outputs the result of the program All fed!.
  • The total output of this command is 66 lines.
24
Q

THE JAR COMMAND

A

the jar command can describe a module. Both of these commands are equivalent:

jar -f mods/zoo.animal.feeding.jar -d

jar --file mods/zoo.animal.feeding.jar --describe-module

The output is slightly different from when we used the java command to describe the module. With jar, it outputs the following:

zoo.animal.feeding jar:file:///absolutePath/mods/zoo.animal.feeding.jar
/!module-info.class
exports zoo.animal.feeding
requires java.base mandated

The JAR version includes the module-info in the filename, which is not a particularly significant difference in the scheme of things. You don’t need to know this difference. You do need to know that both commands can describe a module.

25
Q

THE JDEPS COMMAND

A

The jdeps command gives you information about dependencies within a module.

it looks at the code in addition to the module-info file.

This tells you what dependencies are actually used rather than simply declared.

Let’s start with a simple example and ask for a summary of the dependencies in zoo.animal.feeding. Both of these commands give the same output:

jdeps -s mods/zoo.animal.feeding.jar
jdeps -summary mods/zoo.animal.feeding.jar

Notice that there is one dash (-) before -summary rather than two.

Regardless, the output tells you that there is only one package and it depends on the built-in java.base module.

zoo.animal.feeding -> java.base

Alternatively, you can call jdeps without the summary option and get the long form:

jdeps mods/zoo.animal.feeding.jar
[file:///absolutePath/mods/zoo.animal.feeding.jar]
requires mandated java.base (@11.0.2)
zoo.animal.feeding -> java.base
zoo.animal.feeding -> java.io
java.base
zoo.animal.feeding -> java.lang
java.base
  • The first part of the output shows the module filename and path.
  • The second part lists the required java.base dependency and version number.
  • This has the high-level summary that matches the previous example.
  • Finally, the last four lines of the output list the specific packages within the java.base modules that are used by zoo.animal.feeding.
26
Q

There is not a short form of --module-path in the jdeps command. The output is only two lines:

jdeps -s --module-path mods mods/zoo.animal.care.jar

jdeps -summary --module-path mods mods/zoo.animal.care.jar
A

There is not a short form of –module-path in the jdeps command. The output is only two lines:

zoo.animal.care -> java.base
zoo.animal.care -> zoo.animal.feeding

We can see that the zoo.animal.care module depends on our custom zoo.animal.feeding module along with the built-in java.base.

In case you were worried the output was too short, we can run it in full mode:

jdeps --module-path mods mods/zoo.animal.care.jar

This time we get lots of output:

zoo.animal.care
[file:///absolutePath/mods/zoo.animal.care.jar]
requires mandated java.base (@11.0.2)
requires transitive zoo.animal.feeding
zoo.animal.care -> java.base
zoo.animal.care -> zoo.animal.feeding
zoo.animal.care.details -> java.lang
java.base
zoo.animal.care.details -> zoo.animal.feeding
zoo.animal.feeding
zoo.animal.care.medical -> java.lang
java.base

As before, there are three sections.
* The first section is the filename and required dependencies.
* The second section is the summary showing the two module dependencies with an arrow.
* The last six lines show the package-level dependencies.

27
Q

THE JMOD COMMAND

A

jmod command

JMOD files are recommended only when you have native libraries or something that can’t go inside a JAR file. This is unlikely to affect you in the real world.

The most important thing to remember is that jmod is only for working with the JMOD files.