Multiproject dependencies using Maven style dependencyManagement

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Multiproject dependencies using Maven style dependencyManagement

Ken Avery
Hello,

I am working on a fairly large project containing many gradle sub-projects.  Many of these sub-projects use common dependencies but not necessarily all of them.  I was hoping for some direction on how to specify a library of "versioned" dependencies that individual sub-projects could pick up.  In Maven-land, this capability was supported using <dependencyManagement>.  You can define the dependency including version information here.  Further in your sub-modules, you could then include the dependency by its name excluding the version tag.  The version would be obtained via some parent files dependencyManagement information.

Is there a way to accomplish this using gradle through some common mechanism?  Basically, I want to be able to change the version of a dependency used within the project structure from a central location and have all the consumers of that dependency make use of the new version automatically.

--Ken
Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

Adam Murdoch-3

On 15/12/2010, at 7:24 AM, Ken Avery wrote:

Hello,

I am working on a fairly large project containing many gradle sub-projects.  Many of these sub-projects use common dependencies but not necessarily all of them.  I was hoping for some direction on how to specify a library of "versioned" dependencies that individual sub-projects could pick up.  In Maven-land, this capability was supported using <dependencyManagement>.  You can define the dependency including version information here.  Further in your sub-modules, you could then include the dependency by its name excluding the version tag.  The version would be obtained via some parent files dependencyManagement information.

Is there a way to accomplish this using gradle through some common mechanism?  Basically, I want to be able to change the version of a dependency used within the project structure from a central location and have all the consumers of that dependency make use of the new version automatically.

There isn't a built-in way to do this, but it's pretty easy to achieve.

One option is to set variables on the 'dependencies' object of each project, injected from the root project:

subprojects {
    dependencies {
        someDep = 'org.someorg:someDep:1.9'
        someOtherDep = 'org.someorg:someOtherDep:1.0.1'
    }
}

Then, you would use them like this:

dependencies {
    compile someDep
    runtime someOtherDep
}

You could also move the definitions to a separate file, something like:

root build.gradle:

subprojects {
    apply from: '$rootDir/gradle/dependencyDefinitions.gradle', to: dependencies
}

dependencyDefinitions.gradle:

someDep = 'org.someorg:someDep:1.9'
someOtherDep = 'org.someorg:someOtherDep:1.0.1'


Another option, is to put the definitions in the root project's gradle.properties:

someDep = org.someorg:someDep:1.9
someOtherDep = org.someorg:someOtherDep:1.0.1

Then, you can refer to them in the same way:

dependencies {
    compile someDep
    runtime someOtherDep 
}

At some point, I imagine we'll add some standard way to deal with this problem.


--
Adam Murdoch
Gradle Developer
http://www.gradle.org
CTO, Gradle Inc. - Gradle Training, Support, Consulting
http://www.gradle.biz

Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

frenchyan
Along the line of what Adam is saying you can take a look at the 'org.linkedin.spec' plugin in the gradle-plugins project on github (https://github.com/linkedin/gradle-plugins) which essentially externalizes the dependencies in a separate file entirely (called project-spec.groovy or project-spec.json)

In this file you do something like (example from the project https://github.com/linkedin/linkedin-utils):

// project-spec.groovy
spec = [
    name: 'linkedin-utils',
    group: 'org.linkedin',
    version: '1.2.1',

    versions: [
      groovy: '1.7.5',
      slf4j: '1.5.8' // to be compatible with grails 1.3.5
    ]
]

/**
 * External dependencies
 */
spec.external = [
  ant: 'org.apache.ant:ant:1.8.1',
  groovy: "org.codehaus.groovy:groovy:${spec.versions.groovy}",
  json: 'org.json:json:20090211',
  junit: 'junit:junit:4.4',
  log4j: 'log4j:log4j:1.2.16',
  slf4j: "org.slf4j:slf4j-api:${spec.versions.slf4j}",
  slf4jLog4j: "org.slf4j:slf4j-log4j12:${spec.versions.slf4j}",
  slf4jJul: "org.slf4j:jul-to-slf4j:${spec.versions.slf4j}"
]


And in your build.gradle you simply do:

dependencies {
  compile project(':org.linkedin.util-core')
  compile spec.external.ant
  compile spec.external.slf4j
  compile spec.external.slf4jJul
  compile spec.external.log4j
  compile spec.external.json

  groovy spec.external.groovy
 
  testCompile spec.external.junit
  testRuntime spec.external.slf4jLog4j
}

Yan
Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

Ken Avery
Thank you both, this is very helpful.  

--Ken

On Wed, Dec 15, 2010 at 9:02 AM, frenchyan <[hidden email]> wrote:

Along the line of what Adam is saying you can take a look at the
'org.linkedin.spec' plugin in the gradle-plugins project on github
(https://github.com/linkedin/gradle-plugins) which essentially externalizes
the dependencies in a separate file entirely (called project-spec.groovy or
project-spec.json)

In this file you do something like (example from the project
https://github.com/linkedin/linkedin-utils):

// project-spec.groovy
spec = [
   name: 'linkedin-utils',
   group: 'org.linkedin',
   version: '1.2.1',

   versions: [
     groovy: '1.7.5',
     slf4j: '1.5.8' // to be compatible with grails 1.3.5
   ]
]

/**
 * External dependencies
 */
spec.external = [
 ant: 'org.apache.ant:ant:1.8.1',
 groovy: "org.codehaus.groovy:groovy:${spec.versions.groovy}",
 json: 'org.json:json:20090211',
 junit: 'junit:junit:4.4',
 log4j: 'log4j:log4j:1.2.16',
 slf4j: "org.slf4j:slf4j-api:${spec.versions.slf4j}",
 slf4jLog4j: "org.slf4j:slf4j-log4j12:${spec.versions.slf4j}",
 slf4jJul: "org.slf4j:jul-to-slf4j:${spec.versions.slf4j}"
]


And in your build.gradle you simply do:

dependencies {
 compile project(':org.linkedin.util-core')
 compile spec.external.ant
 compile spec.external.slf4j
 compile spec.external.slf4jJul
 compile spec.external.log4j
 compile spec.external.json

 groovy spec.external.groovy

 testCompile spec.external.junit
 testRuntime spec.external.slf4jLog4j
}

Yan
--
View this message in context: http://gradle.1045684.n5.nabble.com/Multiproject-dependencies-using-Maven-style-dependencyManagement-tp3305232p3306523.html
Sent from the gradle-user mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

alexmcmanus
Do you have a strategy for handling common exclusions? One of the reasons that we use the Maven <dependencyManagement> section is to put in place common exclusions so that we don't have to re-declare them in many sub-projects.

Thanks, Alex.
Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

Peter Niederwieser
In reply to this post by Ken Avery
I prefer the (to my mind) most straight-forward approach, which is to define a map in the root project:

libraries = [
  groovy: "org.codehaus.groovy:groovy-all:1.7.5",
  junit: "junit:junit:4.8.2",
  ...
]

Given that dependencies are project-specific, I don't really see the point of externalizing them. Would be interesting to hear why people do this.

--
Peter Niederwieser 
Developer, Gradle
http://www.gradle.org
Trainer & Consultant, Gradle Inc.
http://www.gradle.biz
Creator, Spock Framework
http://spockframework.org
Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

Rene Groeschke
Hi Peter,

Am 14.02.11 21:24, schrieb Peter Niederwieser:

> I prefer the (to my mind) most straight-forward approach, which is to define
> a map in the root project:
>
> libraries = [
>   groovy: "org.codehaus.groovy:groovy-all:1.7.5",
>   junit: "junit:junit:4.8.2",
>   ...
> ]
>
> Given that dependencies are project-specific, I don't really see the point
> of externalizing them. Would be interesting to hear why people do this.
In our org, we have different multiproject builds, which make heavy use
of the jide lib. To be sure all multiprojects use the same version, an
externalization can be helpful.

regards,
René

--
------------------------------------
Rene Groeschke

[hidden email]
http://www.breskeby.com
http://twitter.com/breskeby
------------------------------------


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

Peter Niederwieser
In reply to this post by alexmcmanus
alexmcmanus wrote
Do you have a strategy for handling common exclusions?
For per-configuration excludes:

allprojects {
  dependencies {
    compile.exclude module: "groovy-all"
  }
}

For per-dependency excludes:

spock = ["org.spockframework:spock-core:0.5-groovy-1.7", { exclude module: "groovy-all"}]

dependencies {
    compile spock
}

--
Peter Niederwieser 
Developer, Gradle
http://www.gradle.org
Trainer & Consultant, Gradle Inc.
http://www.gradle.biz
Creator, Spock Framework
http://spockframework.org
Reply | Threaded
Open this post in threaded view
|

Re: Multiproject dependencies using Maven style dependencyManagement

Michael Campbell
This post has NOT been accepted by the mailing list yet.
In reply to this post by Peter Niederwieser
> Given that dependencies are project-specific, I don't really see the point of externalizing them. Would be interesting to hear why people do this.

They're not, that's the point.  (Except perhaps in very small circumstances.)

In any company that produces multiple builds; perhaps multiple products, one wants at least the dependency versions to be the same across them, generally (and in some cases is mandated due to legal and/or licensing requirements, etc.)  Since they are distinct builds with distinct build files, it is desirable to have the versions of these libraries specified externally so multiple builds aren't depending on different versions of the same library.

This of course can work against you in some cases too, but the maven dependencyManagement feature is a way to *default* the versions of external libs to some value, and the dependency section of each project can *choose* to override that default.