Search code examples
javajava-module

"requires transitive" for modules not working on Eclipse?


I'm starting to study modules, and I would like to try the "requires transitive". So I createad a module for the interface:

module interfacesModule {
    
    exports com.my.interfaces;
    
}

with 1 interface:

package com.my.interfaces;

public interface MyInterface {

    void go();

}

a module for implementation:

module javaModuleA {
    
    requires interfacesModule;
    
    exports com.my.moduleA;
    
}

class:

package com.my.moduleA;

import com.my.interfaces.MyInterface;

public class ClassA implements MyInterface {
    
    public void go() {
        System.out.println("in class A");
    }

}

and the main module:

module mainModule {
    
    requires transitive javaModuleA;
    requires interfacesModule; // this line I want to comment, to use from requires transitive

}

class:

package com.my;

import com.my.interfaces.MyInterface;
import com.my.moduleA.ClassA;

public class Main {
    
    public static void main(String[] args) {
        System.out.println("main java module");
        MyInterface a = new ClassA();
        a.go();
    }

}

This works fine!

Now if i comment the line "requires interfacesModule;" on my main module, should't it still work, as I have the "requires transitive" for javaModuleA?

When I comment it I get "The type com.my.interfaces.MyInterface is not accessible".


Solution

  • A requires transitive javaModuleA; declaration within mainModule implies that a hypothetical module having a requires mainModule declaration would automatically get a dependency as if having a declaration requires javaModuleA; too.

    In other words, what you are trying to do, to get an implicit requires interfacesModule; for mainModule, needs a change in javaModuleA

    module javaModuleA {
        requires transitive interfacesModule;
        exports com.my.moduleA;
    }
    

    Then, mainModule having a requires javaModuleA; or requires transitive javaModuleA; can use exported packages of interfacesModule without the need for a requires interfacesModule;.

    The rationale is that you might have a javaModuleA containing both, the interface and the implementation, as a starting point and decide to refactor the module that has grown too big into javaModuleA and interfacesModule, without the need to adapt the dependent modules. Then, having requires transitive interfacesModule; in javaModuleA allows the modules depending on javaModuleA to continue to work, as if it still was the big module.