Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 236
flakes Avatar asked Feb 28 '16 22:02

flakes


People also ask

What is cyclic dependency in Java?

A circular or cyclic dependency is a situation where two or more independent modules or components rely on each other to function properly. This is referred to as mutual recursion. Circular dependency generally occurs in a modular framework while defining a dependency between modules or components.

Which is correct about module system in Java 9?

Java Module System is a major change in Java 9 version. Java added this feature to collect Java packages and code into a single unit called module. In earlier versions of Java, there was no concept of module to create modular Java applications, that why size of application increased and difficult to move around.

How do you solve circular dependency between modules?

In order to resolve circular dependencies, you should move the common dependencies to another new package and make the two original packages depends just upon on the new one. For instance you could to move the websocket classes to a new package. Also consider to use the transfer object pattern.

How does maven handle cyclic dependency?

Maven does not allow cyclic dependencies between projects, because otherwise it is not clear which project to build first. So you need to get rid of this cycle. One solution is the one you already mentioned, to create another project.


1 Answers

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.

like image 200
Nicolai Parlog Avatar answered Sep 19 '22 17:09

Nicolai Parlog