Question

I have a multi-project (multiple java subprojects) in Grade and I plan to upload it to a maven repository (currently a local one) including the sources and javadoc artifacts. I simply add the following code to each subproject and then maven install does the job:

apply plugin: 'maven'

task sourcesJar(type: Jar, dependsOn:classes) {
        from sourceSets.main.allSource 
        classifier = 'sources' 
} 
task javadocJar(type: Jar, dependsOn:javadoc) {
        from javadoc.destinationDir 
        classifier = 'javadoc' 
}
artifacts { 
        archives jar
        archives sourcesJar 
        archives javadocJar 
}

Now its not that nice to have the same code in 10 subprojects, so I decided I will move this code into the subprojects { ... } configuration of the parent project. However, now it does not work anymore: Only empty sources and javadoc jars are built, the normal jar is ignored, and maven install does not copy the files anymore to the local maven repository. How to do this right?

Thanks.

Was it helpful?

Solution

A parent project's build script gets evaluated before its subprojects' build scripts. When you lift some code to a parent project's build script, you'll have to make sure that the evaluation order stays intact, i.e. that the lifted code doesn't eagerly read properties that are only set by a subproject's build script. For example, if javadoc.destinationDir is set by a subproject's build script, you'll either have to lift that code too, or defer evaluation of the from javadoc.destinationDir expression in the parent build script.

There are several techniques for deferring evaluation. Some properties (like an archive task's from and into) accept a closure; hence you can simply do from { javadoc.destinationDir }. Another option is to use hooks like gradle.projectsEvaluated {}, project.afterEvaluate {}, or task.doFirst {}. The first step in deciding which technique to use is to look up the property in question in the Gradle Build Language Reference.

Without seeing more of your build scripts, my best guess is that your particular problems are related to not lifting apply plugin: "java" into the parent build script's subprojects {} block.

An alternative to configuration injection (e.g. via subprojects {}) is to put common code into a separate build script, and have project build scripts include that code with apply from:. In some cases, this is an easier way to (selectively) share code than configuration injection. Often, the two approaches are used together.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top