<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Fri, Dec 20, 2024 at 1:54 PM Alex Buckley <<a href="mailto:alex.buckley@oracle.com">alex.buckley@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">(I will continue to speak in terms of modules, because there's really no <br>
need to speak in terms of artifacts.)<br>
<br>
There are certainly rules of substitutability that apply to the <br>
declaration of "replacement" modules (e.g., M @ 2.0 replacing M @ 1.0). <br>
One rule is not adding `requires` clauses, as you noted, since it could <br>
create a cycle in the overall graph.</blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">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.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">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.</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">In the case of "replacement" modules for de jure standards like the <br>
{Java, Jakarta} EE Platform (c.f. javax.servlet-api), I would expect the <br>
social mores of the standards body to prevent an implementer from <br>
unhygienic behavior such as adding `requires transitive <br>
com.megacorp.proprietary.api;` to a replacement module.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">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. :-)</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">In the case of "replacement" modules for de facto standards -- "log4j <br>
1.x ... is a widely used library but with known security problems, so a <br>
replacement (e.g. reload4j) is provided instead" -- I would expect basic <br>
competence and conservatism from the developers of the "replacement" <br>
modules.</blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">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*.</div></div></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>