

If one module reads another then, in some situations, it should logically also read some other modules.
The platform’s java.sql
module, e.g., depends upon the java.logging
and java.xml
modules, not only because it contains implementation code that uses types in those modules but also because it defines types whose signatures refer to types in those modules. The java.sql.Driver
interface, in particular, declares the public method
public Logger getParentLogger();
where Logger
is a type declared in the exported java.util.logging
package of the java.logging
module.
Suppose, e.g., that code in the com.foo.app
module invokes this method in order to acquire a logger and then log a message:
String url = ...; Properties props = ...; Driver d = DriverManager.getDriver(url); Connection c = d.connect(url, props); d.getParentLogger().info("Connection acquired");
If the com.foo.app
module is declared as above then this will not work: The getParentLogger
method returns a Logger
, which is a type declared in the java.logging
module, which is not readable by the com.foo.app
module, and so the invocation of the info
method in the Logger
class will fail at both compile time and run time because that class, and thus that method, is inaccessible.
One solution to this problem is to hope that every author of every module that both depends upon the java.sql
module and contains code that uses Logger
objects returned by the getParentLogger
method remembers also to declare a dependence upon the java.logging
module. This approach is unreliable, of course, since it violates the principle of least surprise: If one module depends upon a second module then it is natural to expect that every type needed to use the first module, even if the type is defined in the second module, will immediately be accessible to a module that depends only upon the first module.
We therefore extend module declarations so that one module can grant readability to additional modules, upon which it depends, to any module that depends upon it. Such implied readability is expressed by including the transitive modifier in a requires
clause. The declaration of the java.sql
module actually reads:
module java.sql { requires public java.logging; requires public java.xml; exports java.sql; exports javax.sql; exports javax.transaction.xa; }
The transitive modifiers mean that any module that depends upon the java.sql
module will read not only the java.sql
module but also the java.logging
and java.xml
modules. The module graph for the com.foo.app
module, shown above, thus contains two additional dark-blue edges, linked by green edges to the java.sql
module since they are implied by that module:

Module Implied readability
The com.foo.app
module can now include code that accesses all of the public types in the exported packages of the java.logging
and java.xml
modules, even though its declaration does not mention those modules.
In general, if one module exports a package containing a type whose signature refers to a package in a second module then the declaration of the first module should include a requires transitive
dependence upon the second. This will ensure that other modules that depend upon the first module will automatically be able to read the second module and, hence, access all the types in that module’s exported packages.
Table of Contents
Module javadeveloperzone.base

base-module
module-info.java
module javadeveloperzone.base{ exports com.javadeveloperzone.model; }
Demo.java
package com.javadeveloperzone; import com.javadeveloperzone.Student; public class Demo{ public static void main(String ... args){ System.out.println("Niceee... weldone... welcome to your first module program.."); Student student= new Student(1,"JavaDeveloperZone"); System.out.println(student.getName()); } }
Student.java
package com.javadeveloperzone.model; public class Student{ public int no; public String name; public Student(int no,String name){ this.no=no; this.name=name; } public String getName(){ return this.name; } }
StudentSecure.java
package com.javadeveloperzone.internal; public class StudentSecure{ public int no; public String name; public StudentSecure(int no,String name){ this.no=no; this.name=name; } public String getName(){ return this.name; } }
Module javadeveloperzone.foo
module-info.java
module javadeveloperzone.foo { requires transitive javadeveloperzone.base; exports com.javadeveloperzone.foo; }
FooDemo.java
package com.javadeveloperzone.foo; import com.javadeveloperzone.model.Student; public class FooDemo{ public static void main(String ... args){ System.out.println("Foo modules is accessing javadeveloperzone.base module"); Student student = new Student(1,"FooStudent"); System.out.println(student.getName()); } public static Student getStundetFactory(){ return new Student(1,"FooStudent"); } }
Module javadeveloperzone.bar
module-info.java
module javadeveloperzone.bar{ requires javadeveloperzone.foo; }
BarDemo.java
package com.javadeveloperzone.bar; import com.javadeveloperzone.model.Student; public class BarDemo{ public static void main(String ... args){ Student student = com.javadeveloperzone.foo.FooDemo.getStundetFactory(); System.out.println(student.getName()); } }