Modules   «Prev  Next»

Module Info Exports

D:\ModuleTesting\out\production>
These are the exploded directories for each of the modules. D:\ModuleTesting\out\production>
D:\ModuleTesting\out\production>jdeps org.module.global
org.module.global
 [file:///D:/ModuleTesting/out/production/org.module.global/]
   requires mandated java.base (@11.0.8)
org.module.global -> java.base

   org.pkg.appglobals                                 -> java.lang                                          java.base
D:\ModuleTesting\out\production>

D:\ModuleTesting\out\production>jdeps --list-deps org.module.global
   java.base
jdeps --module-path . org.module.util
In jdeps -p stands for package whereas for java
-p is synonymous with
--module-path.

D:\ModuleTesting\out\production>jdeps --module-path . org.module.util
org.module.util
 [file:///D:/ModuleTesting/out/production/./org.module.util/]
   requires mandated java.base (@11.0.8)
   requires transitive org.module.global
org.module.util > java.base
org.pkg.util -> java.lang java.base
D:\ModuleTesting\out\production>jdeps --module-path . --list-deps org.module.util
   java.base
  


requires and exports

After the introduction of modules in Java 9, you should organize Java applications as modules. A module can declare its dependencies upon other modules using the keyword requires. Requiring a module does not mean that you have access to its public and protected types automatically. A module can declare which packages are accessible to other modules. Only a module's exported packages are accessible to other modules, and by default, no packages are exported. The module declaration in Listing 1-2 exports nothing. The keyword exports is used to export packages. Public and protected types in exported packages and their public and protected members can be accessed by other modules. Listing 2-2 shows the file module-info.java of the module io.vividcode.store.common.persistence. It uses two requires declarations to declare its dependencies upon modules slf4j.api and io.vividcode. store.common. The module slf4j.api comes from the third-party library SLF4J (https://www.slf4j.org/), while
io.vividcode.store.common
is another module in the sample application. The module
io.vividcode.store.common.persistence 
exports its package io.vividcode.store.common.persistence to other modules.
Listing 1-2: Module Declaration of io.vividcode.store.common.persistence
module io.vividcode.store.common.persistence {
requires slf4j.api;
requires io.vividcode.store.common;
exports io.vividcode.store.common.persistence;
}

Please note, when you export a package, you only export types in this package but not types in its subpackages. For example, the declaration exports com.mycompany.mymodule only exports types like com. mycompany.mymodule.A or com.mycompany.mymodule.B, but not types like com.mycompany.mymodule.impl.C or com.mycompany.mymodule.test.demo.D. To export those subpackages, you need to use exports to explicitly declare them in the module declaration.
If a type is not accessible across module boundaries, this type is treated like a private method or field in the module. Any attempt to use this type will cause an error in the compile time, a java.lang. IllegalAccessError thrown by the JVM in the runtime, or a java.lang.IllegalAccessException thrown by the Java reflection API when you are using reflection to access this type.
Let us explore our third module. In the next lesson we will look at how to identify friend modules.