Java 9 Transitive Dependency

Tags:  java

Let’s see how Java handles transitive dependencies. We will be creating three modules

  1. com.moduleone
  2. com.moduletwo
  3. com.modulethree

With these module we will see how transitive keyword works.

Here’s a directory structure we will be creating

└── src
    ├── com.moduleone
    │   ├── com
    │   │   └── moduleone
    │   │       └── ModuleOne.java
    │   └── module-info.java
    ├── com.modulethree
    │   ├── com
    │   │   └── modulethree
    │   │       └── ModuleThree.java
    │   └── module-info.java
    └── com.moduletwo
        ├── com
        │   └── moduletwo
        │       └── ModuleTwo.java
        └── module-info.java

Let’s start with creating com.moduleone

module com.moduleone{
    exports com.moduleone;
}
package com.moduleone;

public class ModuleOne{
    public static void callMe(){
        System.out.println("This is module one code");
    }
}

This was straight foward right!!

Now let’s create com.moduletwo

module com.moduletwo{
    requires com.moduleone;
    exports com.moduletwo;
}
package com.moduletwo;

public class ModuleTwo{}

In com.moduletwo we declared that we required com.moduleone but we are not using it. But for this sake of this example let’s assume com.moduletwo is using com.moduleone code.

Now to the fun part!! Create a third module com.modulethree

module com.modulethree {
    requires com.moduletwo;
}
package com.modulethree;

import com.moduleone.ModuleOne;

public class ModuleThree {
    public static void main(String[] args){
        ModuleOne.callMe();
    }
}

If we run it now, we will get the problem because we have not declared that com.modulethree requires com.moduleone.

We can fix that by adding add requires statement on src/com.modulethree/module-info.java

module com.modulethree {
    requires com.moduletwo;
    requires com.moduleone;
}

But this is not the solution we will be using because we want know how transitive dependencies work on Java 9. So, we will remove that requires statement we added and on com.moduletwo module-info.java file we add transitive keyword after requires like

// src/com.moduletwo/module-info.java
module com.moduletwo{
    requires transitive com.moduleone;
    exports com.moduletwo;
}

Now if you compile our code compile and runs successfully. Notice we are still not declaring that com.modulethree requires com.moduleone but because of transitive dependency we are able to use it. Keyword transitive must come after keyword requires.

If module B has requires transitive dependency on module A and module C simpley requires module B, then module C will have implicit dependence on module A.

GitHub Code