Maven style dependencyManagement

So, I’m working in a fairly large organization with lots of projects, some quite small, some rather large. I’ve implemented a uniform build system with Ant+Ivy, later on we switched to Maven. There are many projects and they need to stay similar in constitution, so that the developers can switch projects easily, etc. Many of the developers don’t need to understand the build scripts that much, they mostly just need to change versions of the dependencies. Also, some of our projects are big multi-projects where we need one place to change the dependency version in.

When considering Gradle as a replacement in a situation like this, one thing that to me seems to be missing is something like Maven’s “dependencyManagement”.

Here’s another thread on this subject:

http://gradle.1045684.n5.nabble.com/Multiproject-dependencies-using-Maven-style-dependencyManagement-td3305232.html

The solutions given there don’t seem satisfactory to me. For one, I want to use the map style when declaring the dependencies. I don’t want to give the developers the task of figuring new names for dependencies. Etc.

So, I’d like to see some way to set at least the versions of the dependencies in the parent pom without creating new variables, etc.

Perhaps something like this in the parent project:

subprojects {
     dependencyManagement {
                   compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
     }
}

Then in a subproject:

subprojects {
     dependencies {
                   compile group: 'org.hibernate', name: 'hibernate-core'
     }
}

This would get the version and other attributes from the dependencyManagement.

To think of it, in our case it’s mostly the problem of configuring the version numbers in one place. I don’t like the idea of creating new variables for this. Perhaps someone can come up with a more elegant solution.

How about a flavor of what Peter suggested in that thread.

In the root project:

subprojects {
  libaries = [
    'hibernate-core':[group:'org.hibernate', name:'hibernate-core', version:'3.6.7.Final']
  ]
}

In the subprojects:

dependencies {
  compile libraries.'hibernate-core'
}

Haven’t tested that, but something like that should work.

It’s good enough to declare ‘libraries’ in the root project (it’s visible from subprojects). Personally I also prefer the short dependency notation ‘org.hibernate:hibernate-core:3.6.7.Final’. For cases where the shared dependency needs advanced configuration (say an exclude) there is ‘dependencies.create()’.

Hi: I tried the solutions, but still run into issues.

So the root build.gradle looks like this:

subprojects {

apply plugin: ‘java’

apply plugin: ‘maven’

apply plugin: ‘eclipse’

cxf_version = ‘2.3.5’

commons_version = ‘1.4.7’

version = ‘0-SNAPSHOT’

repositories {

mavenCentral artifactUrls: [“http://lnyce25218.bankofamerica.com:8081/nexus/content/groups/master”]

}

libraries = [

‘cxf’:[‘org.apache.cxf:cxf-rt-core:2.3.5’]

]

jar {

manifest {

attributes ‘Implementation-Title’: ‘Gradle Quickstart’, ‘Implementation-Version’: version

}

} }

The child project: buildscript {

repositories {

mavenCentral artifactUrls: [“http://lkcma00029.bankofamerica.com:8081/nexus/content/groups/master”]

}

dependencies {

compile libraries.‘cxf’

} }

I kept on getting this error.

  • Where: Build file ‘C:\projects\open\main\wrapper\cxf\build.gradle’ line: 7

  • What went wrong: A problem occurred evaluating project ‘:wrapper:cxf’. Cause: No signature of method: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.compile() is applicable for argum ent types: (java.util.ArrayList) values: [[org.apache.cxf:cxf-rt-core:2.3.5]] Possible solutions: module(java.lang.Object)

  • Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

The debug message shows following: 10:21:12.343 [ERROR] [org.gradle.BuildExceptionReporter]

at org.gradle.launcher.GradleMain.main(GradleMain.java:24) 10:21:12.343 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: groovy.lang.MissingMethodException: No signature of method: org.gradle.a pi.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.compile() is applicable for argument types: (java.util.ArrayList) values: [[ org.apache.cxf:cxf-rt-core:2.3.5]] Possible solutions: module(java.lang.Object) 10:21:12.359 [ERROR] [org.gradle.BuildExceptionReporter]

at org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandl er.methodMissing(DefaultDependencyHandler.groovy:94)

You need to apply the ‘java’ plugin to get a ‘compile’ configuration.

Thanks. I thought when declared apply plugin: ‘java’ at root level, all child projects inherit the plugin automatically. Anyway, I just added plugin to the child project which now looks like this:

buildscript {

apply plugin: ‘java’

repositories {

mavenCentral artifactUrls: [“http://lkcma00029.bankofamerica.com:8081/nexus/content/groups/master”]

}

dependencies {

compile libraries.‘cxf’

} }

And I am still getting this error:

buildscript {

apply plugin: ‘java’

repositories {

mavenCentral artifactUrls: [“http://lkcma00029.bankofamerica.com:8081/nexus/content/groups/master”]

}

dependencies {

compile libraries.‘cxf’

} }

sorry, the build error is listed as follows:

C:\projects\open\main>gradle build

FAILURE: Build failed with an exception.

  • Where: Build file ‘C:\projects\open\main\wrapper\cxf\build.gradle’ line: 9

  • What went wrong: A problem occurred evaluating project ‘:wrapper:cxf’. Cause: No signature of method: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.compile() is applicable for argum ent types: (java.util.ArrayList) values: [[org.apache.cxf:cxf-rt-core:2.3.5]] Possible solutions: module(java.lang.Object)

  • Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

I can’t tell exactly what you are trying to do, but probably the whole ‘buildscript { … }’ needs to go away, and just its contents remain. Also the repository declaration should be changed to:

repositories {
  maven {
    url "http://..."
  }
}

great. Thanks a lot Peter.

Another use of the dependencyManagement feature in Maven is to point to a bill of materials POM, say for CXF, and use the the version numbers of CXFs dependencies, without having to explicitly use them in the “dependencies” section. That way, the requirement is only to rev the version of CXF to retrieve all the versions of its dependencies.

Is it possible to do something similar in Gradle?

A rough equivalent would be a plugin that provides aliases for certain dependencies. Bill of material POMs aren’t currently supported out-of-the-box.