Reputation: 452
I'm developing a multi-module project with gradle/intellij-idea, and here is the structure of my project home:
project/
sub-project-1
/main/resources
sub-project-2
/main/resources
data
/main/resources
/test/resources
As you can see I have multiple sub-projects (all java), how can I make them depend on some common resources (the "data" project, which contains no code but only resources), as well as their own separate resources?
Also it's best that the intellij-idea can pick up these dependencies with JetGradle automatically (JetGradle do just fine picking up the default gradle java project dependencies within each sub project).
Thanks a lot!
Upvotes: 26
Views: 24568
Reputation: 16910
If all your projects are java projects and you apply java
plugin to them you can just do the following. Assuming your directory structure you could do :
def dataMainResourcesPath = rootProject.projectDir.path + '/data/main/resources'
def dataTestResourcesPath = rootProject.projectDir.path + '/data/test/resources'
subprojects.each {
it.sourceSets.main.resources.srcDirs += dataMainResourcesPath
it.sourceSets.test.resources.srcDirs += dataTestResourcesPath
}
in your root build.gradle
.
Upvotes: 0
Reputation: 608
The approach I took was to use project reference
sourceSets {
main {
resources {
srcDirs += [
project(':data').sourceSets.main.resources
]
}
}
}
UPDATE: Tested with Gradle7 and it still works. Tested with java-library plugin.
Upvotes: 21
Reputation: 555
I had another problem with resources in multi-module project, may be it will helpful for somebody.
I have two independent modules:
- database (contains migrations for whole project)
- main (contains business logic(controllers, services and etc))
Also I use Spring-Boot 2 in my project.
I have integration tests in main
and before test is started I need to create schema and tables in DB. But all my migrations (use Flyway
for migration control) in database
module. Path for migration is src/main/resources/db/migrations
.
As a result I need to have all migrations in /test/resources
in order to start tests. Of course, I don't want to duplicate migrations in main
module and I found this solution. I need to add these lines in files in main
module.
builde.gradle
dependencies {
testImplementation "com.example.module:database:$dbMigrationVersion"
}
application-test.yml
spring:
flyway:
locations: classpath:/BOOT-INF/classes/db/migration
After these lines all your migrations from database
module will be in main
module classpath (in our case for test profile). And flyway can execute them before starting tests.
Upvotes: 0
Reputation: 323
sourceSets {
main {
resources {
srcDirs += [
'../sub-project-1/src/main/resources',
'../sub-project-2/src/main/resources',
'../data/src/main/resources'
]
}
}
test {
resources {
srcDir '../data/src/test/resources'
}
}
}
Upvotes: 0
Reputation: 123900
One solution is to apply the Java plugin also to the data
project, and then use regular project dependencies (e.g. dependencies { runtime project(":data") }
). However, this would require a bit of effort to prevent shipping the test resources.
Another solution is not to make data
a Gradle project but literally include its resource directories in the other two projects (sourceSets.main.resources.srcDir "../data/main/resources"; sourceSets.test.resources.srcDir "../data/test/resources"
).
Upvotes: 14
Reputation: 417
And here is version for Kotlin DSL - to sync all resources from :data module to root and all sub-modules build/resources folders:
// Synchronizing resources from :data module to project root: build/resources
synchronizeSharedResources()
subprojects {
// Synchronizing resources from :data module to all submodules: build/resources
synchronizeSharedResources()
}
fun Project.synchronizeSharedResources() {
sourceSets {
main {
resources.srcDir(project(":data").sourceSets["main"].resources.srcDirs)
}
test {
resources.srcDir(project(":data").sourceSets["test"].resources.srcDirs)
}
}
}
Upvotes: 3
Reputation: 2296
You need to choose the project which will hold your resources. All the other projects that require those resources, will add them to the resources
component of the sourceSets.
sourceSets {
data {
resources {
srcDir "${project(':data').projectDir}/src/main/resources"
include "your_pattern_here**"
}
}
main {
resources {
srcDirs += [ data.resources ]
}
}
}
Upvotes: 6
Reputation: 452
Ok, I figured it out. It's actually pretty simple. Just treat the "data" folder as another project and add dependency declarations to sub projects will do the trick. For example:
dependencies {
compile project (':data')
testCompile project (':data')
}
Upvotes: 4