This is my multi-project Gradle setup:
.
└── gradle-module-project
├── application
├── build.gradle.kts
├── gradlew
├── list
├── settings.gradle.kts
└── utilities
application
, utilties
and list
are projects, and inside each one there is a Java Module.
That is, each project has its own src/main/java/module-info.java
file and build.gradle.kts
file.
application
module depends on utilities
module, and utilities
module depends on list
module.
build.gradle.kts
at the root contains the following:
subprojects {
..
plugins.withType<JavaPlugin>().configureEach {
configure<JavaPluginExtension> {
modularity.inferModulePath.set(true)
}
}
..
}
What I find strange is that inside each sub-project, the build.gradle.kts
is required to list the dependencies.
For example, application
-> build.gradle.kts
contains:
plugins {
application
}
dependencies {
implementation(project(":utilities"))
}
..
Why does build.gradle.kts
for application
have to include implementation(project(":utilities"))
?
When the module-info.java
inside application
already specifies what that module depends on.
Doesn't this seem like duplication?
Is it intended that the dependency must be specified in both module-info.java
and build.gradle.kts
?
When using Java Modules with Gradle, dependencies have to be specified twice: once for the benefit of the module system and again for the benefit of the build tool.
I've been following along with the Easy Text demo application in Java 9 Modularity by Sandor Mak and Paul Bakker, which is a multi-module project. The module-info.java
for one module is:
module easytext.cli {
requires easytext.analysis;
}
When I wrap it in Gradle, in my build.gradle
file I also need:
dependencies {
implementation project(':easytext.analysis')
}
Perhaps it's just a matter of time before the tooling catches up and we won't have to do both.
Also check out Paul Bakker's JavaOne presentation Building JPMS Modules with Java in which he goes through the fine-detail of building multiple-module Java/Groovy/Kotlin projects with Gradle.