[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