The definition of `requires`
Alex Buckley
alex.buckley at oracle.com
Fri Dec 20 18:57:55 UTC 2024
On 12/20/2024 6:51 AM, David Lloyd wrote:
> A build system like Maven presents dependency lists in terms of
> artifact coordinates, which generally resolve to a specific
> artifact. In some cases, there will be a dependency on some kind of
> API with a scope of "provided", indicating "when I run this thing in
> the target environment, we need these classes/packages to be
> available".
>
> The actual artifact (or one of its transitive dependencies) found in
> the run time environment may be entirely different.
The dependency that is expressed by users is not literally on an API,
but rather on the name of a well-known artifact, e.g.,
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
This forces a JAR file called javax.servlet-api-3.0.1.jar (the "actual
artifact") to exist on the user's system. The trick is that the bits of
the JAR file (and hence its dependencies) differ from implementer to
implementer. There was an out-of-band social mechanism called "The Java
EE Platform" to ensure that the bits in such JAR files always contain a
literal API consisting of Java classes and interfaces.
Turning to `requires`, the design of the Java module system anticipated
that a tool outside the JDK could inspect the module name specified by
`requires` and choose the "best" version of a module with that name.
This is why `requires` does not specify version constraints, per
https://openjdk.org/projects/jigsaw/spec/reqs/#version-selection.
We understand that if `requires M;` ends up resolving the module M @ 1.0
(because a build system happened to make M @ 1.0 observable), then the
module graph could look different than if M @ 2.0 is resolved. M @ 2.0
can of course express different dependences than M @ 1.0. Notice that in
this paragraph, I have spoken in terms of modules, not in terms in JAR
files or paths.
Accordingly, it is legitimate to view the module name specified by
`requires` as not indicative of a particular JAR file. That is, not
indicative of an "actual artifact". Modules are more abstract than
artifacts, per
https://mail.openjdk.org/pipermail/jpms-spec-experts/2017-February/000582.html.
Alex
More information about the jigsaw-dev
mailing list