[External] : Re: The definition of `requires`
Alex Buckley
alex.buckley at oracle.com
Fri Dec 20 22:47:26 UTC 2024
On 12/20/2024 12:48 PM, David Lloyd wrote:
> 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).
We view _encapsulation_ as being achieved via _accessibility_: the
ability of the JVM to prevent access to classes if either the accessing
module does not consume (does not "read") the classes' module, or if the
accessing module does consume ("read") the classes' module but the
classes' module does not export the classes.
Let's talk about the A->B->C scenario.
Suppose a consumer of A, called M, obtains a reference to an object of a
class defined in C. This can happen in innumerable ways, and the
reference can have a variety of types: Object, Serializable, some
interface defined by A, etc. Even if C exports the class, M does not
consume (does not "read") C. So, no access for M's code to C's code. M's
code cannot do anything interesting with the object it obtained.
This accessibility mechanism is orthogonal to class loaders. All the
classes in M, A, B, and C could be defined by the same class loader.
M can easily arrange to consume C, via `requires` or addReads. If that
happens, then C's predilection for exporting classes means that M's code
can access C's code. Of course it can! If C didn't want arbitrary code
to access its classes, then C should have qualified its exports.
When you say that M should "not have to worry about what's going on with
C", I think you mean that _even if C exports all its classes and even if
M arranges to consume C_, some additional mechanism should provide
_isolation_ for C, such that M's code cannot access C's code.
Such isolation would open the door to replacing C by D -- a module with
different bits, and different dependencies, but the same name and
exports as C. D and all of its dependencies would be outside the worry
range of M, just as C was.
Alex
More information about the jigsaw-dev
mailing list