Let us make a new module v2ch09.requiremod in which a program uses a JOptionPane to show the “Hello, Modular World” message:
package com.horstmann.hello;
import javax.swing.JOptionPane;
public class HelloWorld
{
public static void main(String[] args)
{
JOptionPane.showMessageDialog(null, “Hello, Modular World!”);
}
}
Now compilation fails with this message:
error: package javax.swing is not visible
(package javax.swing is declared in module java.desktop,
but module v2ch09.requiremod does not read it)
The JDK has been modularized, and the javax.swing package is now contained in the java.desktop module. Our module needs to declare that it relies on that module:
module v2ch09.requiremod
{
requires java.desktop;
}
It is a design goal of the module system that modules are explicit about their requirements, so the virtual machine can ensure that all requirements are fulfilled before starting a program.
In the preceding section, the need for explicit requirements did not arise because we only used the java.lang and java.io packages. These packages are included in the java.base module which is required by default.
Note that our v2ch09.requiremod module lists only its own module requirements. It requires the java.desktop module so that it can use the javax.swing package. The java.desktop module itself declares that it requires three other modules, namely java.datatransfer, java.prefs, and java.xml.
Figure 9.1 shows the module graph whose nodes are modules. The edges of the graph—the arrows joining nodes—are either declared requirements or the implied requirement on java.base when none is declared.
You cannot have cycles in the module graph—that is, a module cannot directly or indirectly require itself.
A module does not automatically pass on access rights to other modules. In our example, the java.desktop module declares that it requires java.prefs, and the java.prefs module declares that it requires java.xmt. That does not give java.desktop the right to use packages from the java.xmt module. It needs to explicitly declare that requirement. In mathematical terms, the requires relationship is not “transitive.” Generally, this behavior is desirable because it makes requirements explicit, but as you will see in Section 9.11, “Transitive and Static Requirements,” on p. 519, you can relax it in some cases.
Source: Horstmann Cay S. (2019), Core Java. Volume II – Advanced Features, Pearson; 11th edition.