Search code examples
javajava-9java-platform-module-systemjava-modulemodule-info

Will Cyclic Module Dependencies be Possible in Java 9?


In Java 9, will cyclic modules be allowed? If no, what are the reasons?

module com.foo.bar {
    requires com.foo.baz;
    exports com.foo.bar.fizz;
}

module com.foo.baz {
    requires com.foo.bar;
    exports com.foo.baz.buzz;
}

Solution

  • Nope.

    Documentation

    Interestingly enough neither the State of the Module System nor the Jigsaw Quick Start Guide address this issue. One source (found by Andy) is a JavaOne talk by Alex Buckley (see him explain it here). A more recent one is the list of open issues, which explicitly mentions cyclic dependencies:

    The current draft disallows cycles when the module graph is initially resolved at compile time, link time, and run time. Cycles can arise later on at run time if readability edges are added for automatic modules, or via reflection. [...] This constraint is not, however, a documented requirement [...].

    Justification

    Cyclic dependencies are bad, mkay. ;)

    They emerge when two entities (methods, classes, modules, projects, ...) collaborate but are not sufficiently decoupled. For users as well as maintainers this coupling means that they can not use or improve one without considering the other. But this is exactly the benefit modularization is trying to achieve.

    From the issue list, linked above:

    The rationale for disallowing cycles during resolution is that it makes the module graph easier to reason about, it simplifies the module system itself, and that, philosophically, any modules involved in a cycle are logically one module anyway, so they should be defined as such in the first place.

    Experimentation

    I've created a little demo project on GitHub that contains two cycles (pair: two -> one -> two; triple: three -> two -> one -> three). Trying the multi-module compilation as shown in the quick start guide, these are the results:

    ./compile.sh
     > creating clean directories
     > compiling and packaging cycle "pair"
    src/org.codefx.demo.cyclic.pair.one/module-info.java:2: error: cyclic dependence involving org.codefx.demo.cyclic.pair.two
            requires org.codefx.demo.cyclic.pair.two;
                                                ^
    1 error
     > compiling and packaging cycle "triple"
    src/org.codefx.demo.cyclic.triple.three/module-info.java:2: error: cyclic dependence involving org.codefx.demo.cyclic.triple.two
            requires org.codefx.demo.cyclic.triple.two;
                                                  ^
    1 error
    

    So you can't even compile the modules, let alone use them in a configuration.