I asked a Create multiple shadowJars for each flavor of application on SO but haven’t received any attention there. Even though shadowJar related questions are not precisely a core gradle issue, but I suspect the issue is with the way I’m trying to use gradle rather than the shadowJar plugin. Trying java plugin, for example runs into the same problem.
I’m experimenting with gradle and trying to setup a system that builds different flavors (brands) of an application, which differ by configuration mainly. What I have so far are two versions of the build scripts - both not working.
Version 1
First flavor specific resource folder flavor-res
is added to sourcesets
, which achieves overwriting some default resources. A task rule defines tasks for each flavor, which should (ideally) trigger build of the whole jar.
This works fine and generates the required jar, for one flavor at a time, like
gradle clean flavorOne
but the shadowJar
task runs only once, if I do
gradle clean flavorOne flavorTwo
Stripped down Script:
sourceSets {
main {
...
resources {
srcDirs = ['src/main/resources', "${project.buildDir}/flavor-res/"]
}
}
}
shadowJar { classifier = 'SNAPSHOT' }
tasks.addRule("Pattern: flavor<Name>") { String taskName ->
if (taskName.startsWith("flavor")) {
String flavorName = (taskName - "flavor")
String flavorOutDir = "${project.buildDir}/${flavorName}"
// Set output folder and jar name
task("${taskName}Configure") {
outputs.dir(flavorOutDir)
doFirst {
archivesBaseName = flavorName
project.buildDir = flavorOutDir
}
}
// Copy res to folder used in sourcesets
task("${taskName}CopyResources") {
mustRunAfter = ["${taskName}Configure"]
outputs.dir("${project.buildDir}/flavor-res")
doFirst {
copy {
from "flavors/${flavorName}/"
into "${project.buildDir}/flavor-res/"
}
}
}
shadowJar.mustRunAfter = ["${taskName}Configure", "${taskName}CopyResources"]
// Define task that depends on shadowJar
task(taskName, dependsOn: ["${taskName}Configure", "${taskName}CopyResources",
shadowJar]) {
println "Configuring ${taskName}"
}
}
Sensing that it probably doesnt work because the change detection somehow doesnt work, I tried an alternative approach. Here is a simplified version of script
Version 2
Modified the rule to define a shadowJar
dynamic task for each flavor.
/* Removed sourceSets in this version */
shadowJar { classifier = 'SNAPSHOT' }
tasks.addRule("Pattern: flavor<Name>") { String taskName ->
if (taskName.startsWith("flavor")) {
String flavorName = (taskName - "flavor")
String flavorOutDir = "${project.buildDir}/${flavorName}"
// Set resources for main sourceset
task("${taskName}Configure") {
outputs.dir(flavorOutDir)
doFirst {
archivesBaseName = flavorName
sourceSets.main.resources.srcDirs = ['src/main/resources', "${flavorOutDir}/flavor-res"]
project.buildDir = flavorOutDir
}
}
task("${taskName}CopyResources") {
outputs.dir("${flavorOutDir}/flavor-res")
dependsOn "${taskName}Configure"
doFirst {
copy {
from "flavors/${flavorName}/"
into "${project.buildDir}/flavor-res/"
}
}
}
// This should shadowJar for each flavor - but generate jars dont have the required artifacts.
task ("${taskName}Build", type: ShadowJar) {
from sourceSets.main.output
configurations = [ configurations.runtime ]
classifier = 'SNAPSHOT'
dependsOn "${taskName}CopyResources"
}
task(taskName, dependsOn: ["${taskName}Build"]) {
}
}
}
However, now, the generated jars are malformed. The first flavor just gets the artifacts for main, but no showed jars. The second jar just has the manifest and nothing else.
What would be the correct way of achieving that? I would appreciate if someone could point out why what I’ve done so far behaves the way it does.