Draft JPMS Public Review specification

David M. Lloyd david.lloyd at redhat.com
Tue Mar 14 18:53:43 UTC 2017

On 03/14/2017 10:59 AM, mark.reinhold at oracle.com wrote:
> 2017/3/12 5:40:00 -0700, rfscholte at apache.org:
>> David suggested to reopen #CyclicDependences and based on his story I
>> agree that this one should be reconsidered. The problem can arise at
>> runtime when a combination of versions of different modules come together
>> and create a cycle, whereas at compile time (with a different set of
>> modules) everything looks fine. I don't think that it is the
>> responsibility of the JVM to prevent cycles, there are other tools which
>> can detect cycles and warn about it and where you can suppress it, because
>> it is intended.
>> Based on the Java Platform Module System: Requirements[4] I don't see any
>> goal specification regarding cyclic dependencies. It looks more like a
>> bonus you achieved with the JDK/JRE itself to make it possible to link
>> small assemblies, but the outer world sometimes needs this trick.
> It's true that the agreed requirements don't say anything about whether
> or not cycles should be allowed.  Disallowing them does, however, bring a
> number of significant advantages, as noted in the issue statement [6].
> The designers of some other module systems have found it useful to allow
> cycles, but JPMS differs from those in a couple of essential ways that
> bear upon this issue:
>   - JPMS is not highly dynamic, so if a cycle arises while configuring
>     a layer then that fact will be reported early, when it's easier to
>     diagnose, rather than at some (possibly much) later point in time.

This is only true if you're building all your modules at one time, in 
the exact versions and arrangement in which they will run.  Experience 
shows that Maven has become ubiquitous specifically because this is 
almost never true in practice (except for a few specifically monolithic 
and self-contained projects, like the JDK itself for example); at 
test/run time, environments are usually an accumulation of modules built 
at many different times and places.  Therefore enforced prevention of 
cycles beyond compile-time is likely to *cause* unexpected problems, not 
avoid them, for reasons I've explained in detail previously.  A user 
will not be thankful that we have held their hand if their project only 
fails in production after some third-party dependency has been updated 
and unexpectedly introduces a long cycle - something we've observed in 
the wild quite frequently.

>   - JPMS aims to provide a clear migration path for existing components,
>     but it assumes that components can and will be revised during that
>     process.  If a cyclic module graph arises then the maintainers of
>     the relevant components should consider whether a service should
>     be introduced in order to break the cycle.

It does not follow that users will want to (or even be able to) 
substantially refactor the modules in their deployment; editing a 
descriptor is one thing but a possibly major refactor is something 
completely different.

> Taken together with the compelling arguments against cyclic module
> relationships made by at least one noted expert in the field [7], on
> balance I think it's best to disallow cycles in JPMS for now.  If actual
> experience with JPMS as used directly by developers -- rather than as
> an embedding target for other module systems -- suggests that we should
> allow cycles then we could enable them in a future release.  If we enable
> them now, however, then we can never take them back.

Why not compromise by disallowing cycles at compilation time, but not 
enforcing the restriction at run time?  This satisfies your desire to 
report early, and matches the behavior of current build tools, but also 
avoids the inevitable packaging issues in large-application 
environments, and follows the principle of least surprise for end users.

Put another way, what would the late/run-time part of cycle enforcement 
gain anyone?


More information about the jpms-spec-experts mailing list