21
Sep 09

Grails 1.2 dependency management

Grails 1.2 comes with a great dependency management. You no longer have to manually manage the dependencies and don’t have to resort to using maven for this task. Grails uses Apache Ivy under the hood for transitive dependency management. Ivy allows to set up multiple resolvers and resolution patterns though allowing you to adapt to maven repositories and many other, even custom repository schemes. Grails takes it a step further and allows you to do this with a pretty nice looking DSL.

Application dependencies are configured in BuildConfig.groovy file and they look something like this…

grails.project.dependency.resolution = {
  inherits "global" // inherit Grails' default dependencies
  log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
  repositories {
    grailsHome()
    mavenCentral()

    mavenRepo "http://download.java.net/maven/2/"
    mavenRepo "http://repository.jboss.com/maven2/
  }
  dependencies {
    // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
    runtime 'com.mysql:mysql-connector-java:5.1.5'
  }
}

By default, grails pulls dependencies from your grails installation library. You can also uncomment (as you see above), the mavenCentral() repository. These are the defaults and don’t require any more configuration. You can also specify a custom maven-compatible repo URL using mavenRepo.

There is also a flat dir resolver, allowing you to resolve dependencies to some local directory. You can do this as:

flatDir name: ‘localRepo’, dirs:’/some/path/to/repo’

So I naively tried using flatDir to resolve a local maven repo, which of course didn’t work, since it’s not defined with the maven artifact resolution pattern. In order for that to work, you have to define your own resolver for now. I just submitted a patch to add a mavenLocal() resolver. Should make it to HEAD shortly.

So, for now, you can do

  private org.apache.ivy.plugins.resolver.DependencyResolver createLocalMavenResolver() {
    def localMavenResolver = new FileSystemResolver();
    localMavenResolver.local = true
    localMavenResolver.name = "localMavenResolver"
    localMavenResolver.m2compatible = true
    localMavenResolver.addArtifactPattern "${userHome}/.m2/repository/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"
    def ivySettings = new IvySettings()
    ivySettings.defaultInit()
    localMavenResolver.settings = ivySettings
    return localMavenResolver
  }

Then use this method as…

resolver createLocalMavenResolver()

resolver method basically allows you to specify your own Ivy resolver. But that seems like too much work for something as common as local maven repo, especially since anyone who’s going to use maven dependency artifacts, probably will install some locally.

So once the patch makes it in, you can just uncomment…

mavenLocal()

By default this resolver will resolve dependencies in home_dir/.m2/repository, but you can also specify your own path to the repository by just passing it as an argument…

mavenLocal(“/opt/maven/repository”)

Grails 1.2 is beginning to look very exciting.

Tags: , ,

4 comments

  1. That’s very useful. Now we only desperately need a way to have grails output the rewolved classpath to use it in eclipse, netbeans or whatever.

  2. If you’re addicted to your pom.xml file then we have even added the ability to read dependencies from the pom.xml instead of using the DSL. All in all, Grails 1.2 will give you significantly better control over dependencies and how they are resolved.

  3. If you want to create a custom resolver, do you put your custom code in BuildConfig.groovy. I need to create a custom resolver because my local and enterprise repository are ivy repository and the structure and the patterns are different. I have try to put the code in the BuildConfig.groovy but groovy is unable to resolve FileSystemResolver. Any hints

  4. Martin, the custom system resolver above works fine by just sticking it into the BuildConfig.groovy. When/where do you get the import error, in your IDE or during a grails phase? It’s important, as in IDE you might have to add an import statement in the BuildConfig.groovy file. Try to fully qualify it as well, that might help.

Leave a comment