[External] : Re: The definition of `requires`

David Lloyd david.lloyd at redhat.com
Fri Dec 20 20:48:34 UTC 2024


On Fri, Dec 20, 2024 at 1:54 PM Alex Buckley <alex.buckley at oracle.com>
wrote:

> (I will continue to speak in terms of modules, because there's really no
> need to speak in terms of artifacts.)
>
> There are certainly rules of substitutability that apply to the
> declaration of "replacement" modules (e.g., M @ 2.0 replacing M @ 1.0).
> One rule is not adding `requires` clauses, as you noted, since it could
> create a cycle in the overall graph.


That is maybe more interesting than it appears. A defining feature of
moving from an older to a newer version of a library is that something has
changed, improved, been added, or been rewritten. Traditionally, library
authors were fairly cavalier about having their consumers be explicitly
ignorant of their implementation details, but it would not be at all
unusual to expect an implementation dependency to be added or changed (or
removed, in the case of cleaning up deprecated features), just speaking
historically.

Likewise it would not be unusual for a module to add new packages in the
course of its natural evolution. `requires transitive` seems like a
variation on this case.


> In the case of "replacement" modules for de jure standards like the
> {Java, Jakarta} EE Platform (c.f. javax.servlet-api), I would expect the
> social mores of the standards body to prevent an implementer from
> unhygienic behavior such as adding `requires transitive
> com.megacorp.proprietary.api;` to a replacement module.
>

One of the nice things about these kinds of standards is that they tend to
be nicely divided between API and implementation, and if you're lucky,
they'll use something like service loader to allow for proper isolation.
This is definitely far from the common case out in the wild. We've
struggled to change that for a decade plus, but have made little headway. I
can't even get my own department to do this. :-)

In the case of "replacement" modules for de facto standards -- "log4j
> 1.x ... is a widely used library but with known security problems, so a
> replacement (e.g. reload4j) is provided instead" -- I would expect basic
> competence and conservatism from the developers of the "replacement"
> modules.


That might be taking it a little far. A replacement library (or even an
original library) might be obligated to change one of *its* implementation
dependencies (like a utility library) due to security problems of this
sort, and since it is an implementation detail, it would not be natural to
expect any user to consider that the third library's having a different
API/package set could introduce some new hygiene problem. We've always
considered it to be a natural property of encapsulation for the consumers
of A to not have to worry about what's going on with C in an A->B->C
scenario (or its presence or absence). But, with flat or even hierarchical
layers, this kind of concern for transitive hygiene at all levels (from the
user's code all the way to the furthest transitive dependency of the
runtime environment) arises as an artifact, which is an unfortunate
violation of encapsulation. It would be nice to improve this *somehow*.
-- 
- DML • he/him
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jigsaw-dev/attachments/20241220/0224e609/attachment.htm>


More information about the jigsaw-dev mailing list