How to specify dependencies in a multi-project build on jar tasks from a project


(Jeremy Towne) #1

I have a multi-project build and I want to specify compile dependencies of one project on the output of the jar tasks from a different project. I am applying the ‘groovy’ plugin to my projects. I have tried putting a compile dependency on the ‘archives’ configuration of the dependent project: (project a depends on jar tasks of project b)

//a.gradle
dependencies {
    compile project(path: ':b', configuration: 'archives')
}

and I add the jar tasks to the configuration like:

//b.gradle
project.artifacts {
    archives myJarTask
}

When I list all the archives of the configuration I can see my jar tasks that I want, and I also see the jar task created by the groovy plugin. When I run task ‘:a:dependencies’ I only see the dependency on the jar task that the groovy plugin added. The project builds/compiles fine, but incorrect information is going into the pom file of jars created by project :a (because I disable the jar task created by the groovy plugin as I do not want this jar to be created). Now I tried to create a new configuration and add only my jars to it and specify it as a compile dependency so it wouldn’t be getting the jar added by the groovy plugin.

//a.gradle
dependencies {
    compile project(path: ':b', configuration: 'myConfig')
}
  //b.gradle
archives {
    myConfig myJarTask
}

And when i println the contents of this configuration

project.configurations.myConfig.allArtifacts.each {
    println it
}

it contains all of the jars that I want, but when I run ‘:a:dependencies’ it still only shows the compile dependency on the jar generated by the groovy plugin.

Is my only solution here to not use the ‘groovy’ plugin and use ‘groovy-base’?

EDIT: I made an example project of my problem here: https://github.com/jeremytowne/gradle-dependency-test


(René Groeschke) #2

Hello Jeremy,

what you introduce between a and b is a project dependency. what you see when running “:a:dependencies” is a reference on project b. the artifact name, version and group are taken from the project model of b and not from the myJar task. The base name is not considered here. To fix this you can declare a classifier value in myJar. Then you can see, that a depends on b with the classifier you assigned to myJar.

A much more cleaner way would be (as you already suggested) to go with the groovy-base plugin and model your custom project layout from scratch instead of disabling not used things like tasks/configurations from the plain groovy plugin.

cheers, René


(Jeremy Towne) #3

Hi René,

Thank you for the response. I updated my test project (https://github.com/jeremytowne/gradle-dependency-test) to use the ‘groovy-base’ plugin instead of the ‘groovy’ plugin and I added a classifier value to the myJar task of :b. I am still getting the same issue where :a’s dependencies are being taken from the project model and not from the jar task. Do I have to change the way I specify the dependency in :a (for example to specify the classifier value somehow)? i.e. change this code:

dependencies {
    compile project(path: ':b', configuration: 'myArchives')
}

Jeremy


(Jeremy Towne) #4

So I figured out how to fix the issue I was having. The main issue was not exactly listing the dependencies, but rather adding the correct dependencies to the pom. You can see my solution in my test project (https://github.com/jeremytowne/gradle-dependency-test). I ended up using the ‘maven-publish’ plugin to upload, and used the following code to check for project configuration dependencies and add them to the pom:

def addAllProjectDependenciesToPom(pom, Configuration configuration){
    pom.withXml { provider ->
        def node = provider.asNode()
        def dependenciesNode = node.dependencies
        if(!dependenciesNode) {
            dependenciesNode = node.appendNode('dependencies')
        }
        configuration.allDependencies.withType(ModuleDependency).each{ moduleDep ->
            if(moduleDep instanceof ProjectDependency) {
                moduleDep.getProjectConfiguration().getAllArtifacts().each { artifact ->
                    def artifactId = "${artifact.name}" + (artifact.classifier ? "-${artifact.classifier}" : "")
                    addDependencyNodeToPom(dependenciesNode, configuration.name, moduleDep.group, artifactId, moduleDep.version)
                }
            } else {
                addDependencyNodeToPom(dependenciesNode, configuration.name, moduleDep.group, moduleDep.name, moduleDep.version)
            }
        }
    }
}
  def addDependencyNodeToPom(dependenciesNode, scope, group, artifact, version) {
    def dependencyNode = dependenciesNode.appendNode('dependency')
    dependencyNode.appendNode("scope", scope)
    dependencyNode.appendNode("groupId", group)
    dependencyNode.appendNode("artifactId", artifact)
    dependencyNode.appendNode("version", version)
}