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