The Java Platform Plugin
The Java Platform plugin brings the ability to declare platforms for the Java ecosystem. A platform can be used for different purposes:
-
a description of modules which are published together (and for example, share the same version)
-
a set of recommended versions for heterogeneous libraries. A typical example includes the Spring Boot BOM
-
sharing a set of dependency versions between subprojects
A platform is a special kind of software component which doesn’t contain any sources: it is only used to reference other libraries, so that they play well together during dependency resolution.
Platforms can be published as Maven BOMs or with the experimental Gradle metadata file format.
✨
|
The |
Usage
To use the Java Platform plugin, include the following in your build script:
Groovy
Kotlin
plugins {
id 'java-platform'
}
API and runtime separation
A major difference between a Maven BOM and a Java platform is that in Gradle dependencies and constraints are declared and scoped to a configuration and the ones extending it. While many users will only care about declaring constraints for compile time dependencies, thus inherited by runtime and tests ones, it allows declaring dependencies or constraints that only apply to runtime or test.
For this purpose, the plugin exposes two configurations that can be used to declare dependencies: api
and runtime
.
The api
configuration should be used to declare constraints and dependencies which should be used when compiling against the platform, whereas the runtime
configuration should be used to declare constraints or dependencies which are visible at runtime.
Groovy
Kotlin
dependencies {
constraints {
api 'commons-httpclient:commons-httpclient:3.1'
runtime 'org.postgresql:postgresql:42.2.5'
}
}
Note that this example makes use of constraints and not dependencies. In general, this is what you would like to do: constraints will only apply if such a component is added to the dependency graph, either directly or transitively. This means that all constraints listed in a platform would not add a dependency unless another component brings it in: they can be seen as recommendations.
✨
|
For example, if a platform declares a constraint on |
By default, in order to avoid the common mistake of adding a dependency in a platform instead of a constraint, Gradle will fail if you try to do so. If, for some reason, you also want to add dependencies in addition to constraints, you need to enable it explicitly:
Groovy
Kotlin
javaPlatform {
allowDependencies()
}
Local project constraints
If you have a multi-project build and want to publish a platform that links to subprojects, you can do it by declaring constraints on the subprojects which belong to the platform, as in the example below:
Groovy
Kotlin
dependencies {
constraints {
api project(":core")
api project(":lib")
}
}
Publishing platforms
Publishing Java platforms is done by applying the maven-publish
plugin and configuring a Maven publication that uses the javaPlatform
component:
Groovy
Kotlin
publishing {
publications {
myPlatform(MavenPublication) {
from components.javaPlatform
}
}
}
This will generate a BOM file for the platform, with a <dependencyManagement>
block where its <dependencies>
correspond to the constraints defined in the platform module.
Consuming platforms
Because a Java Platform is a special kind of component, a dependency on a Java platform has to be declared using the platform
or enforcedPlatform
keyword, as explained in the managing transitive dependencies section.
For example, if you want to share dependency versions between subprojects, you can define a platform module which would declare all versions:
Groovy
Kotlin
dependencies {
constraints {
// Platform declares some versions of libraries used in subprojects
api 'commons-httpclient:commons-httpclient:3.1'
api 'org.apache.commons:commons-lang3:3.8.1'
}
}
And then have subprojects depend on the platform to get recommendations:
Groovy
Kotlin
dependencies {
// get recommended versions from the platform project
api platform(project(':platform'))
// no version required
api 'commons-httpclient:commons-httpclient'
}