How can I include a dependant jar in a multi project grails / gradle build?

Also posted on stackoverflow.com here: http://stackoverflow.com/questions/13378289/how-can-i-include-a-dependant-jar-in-a-multi-project-grails-gradle-build

I have the following setup within my project…

  • A multi project gradle build for a SOA style project, wired together using rabbitmq and spring integration. - Contains a number of grails projects as well as plain java / groovy projects to represent the services. - Alongside each of the service projects are a project (jar) containing all of the public interfaces (and messages) for the service that can be proxied using spring integration. - The projects are related to each other using gradle dependencies and then I generate IntelliJ projects files using the gradle idea plugin.

What I want to do is:

  • Include the interfaces jar in the grails project so that I can use spring integration there to proxy my calls into the services via rabbitmq. - When I run the grails app have this intefaces jar built and included within grails. - When I run the grails app from IntelliJ have it compile the latest version of the interfaces and include them in the grails project. - When I build the entire project from gradle, have gradle correctly associate the interfaces jar with the grails app. - Ideally I would love to be able to do this just using dependency declaration within gradle, but this is probably a pipe dream…

What are my options?

  1. Add a task into the grails build lifecycle within gradle to build any dependant jars and copy them into the grails lib folder? 2. Hook into the grails build lifecycle by using Events.groovy or similar to call out to grails to build and package the dependant jars. This would cover both the IntelliJ and command line routes. 3. Build the interfaces as a grails plugin? I had discounted this as they also need to be used from non-grails projects.

Any help / advice would be appreciated.

I am currently working with the Grails guys on a Gradle plugin for building Grails projects that will make this much easier (https://github.com/grails/grails-gradle-plugin).

In the meantime, I suggest asking on the Grails list as I know there are people who are doing this right now. But be warned, it’s not always pretty.

Thanks, will do…

I was hoping to do something like this in the mean time, copying the artifacts from the dependant project into my grails lib at some point during the gradle grails build:

task syncDependencies(type: Sync) {
    from project(':dependent-project').configurations.archives.allArtifacts.files
    into "$projectDir/lib"
}

The problem that I seem to be having is that the “archives” configuration has not been created by the java plugin on the dependent project by the time this configuration section runs.

I’m sure this must be just a case of doing this configuration at a different point in the build lifecycle.

My solution for the moment is to:

  • Use the grails / gradle plugin to build the grails projects. - Use this plugin to run my grails apps, ie. gradle grails-run-app. - Hook into the grails-run-app task in gradle (which is created on the fly) to call a task which builds and copies the dependencies into the lib directory.

This doesn’t help a whole load with IntelliJ at the moment but I will run my gradle tasks as IntelliJ run configurations.

My build.gradle is as follows (dependent-project is being jarred and put in lib in this example):

import org.grails.gradle.plugin.GrailsTask
  evaluationDependsOn(':dependent-project')
  buildscript {
    repositories {
        mavenCentral()
        mavenRepo name: "grails", url: 'http://repo.grails.org/grails/repo'
    }
    dependencies {
        classpath "org.grails:grails-gradle-plugin:1.1.1-SNAPSHOT"
    }
}
  repositories {
    mavenCentral()
    mavenRepo name: "grails", url: 'http://repo.grails.org/grails/repo'
}
  ext {
    version = "1.0"
    grailsVersion = "2.2.0.RC2"
    grailsTaskPrefix = "grails-"
}
  apply plugin: "grails"
  dependencies {
    ['dependencies', 'resources', 'core', 'test', 'hibernate', 'plugin-datasource', 'plugin-domain-class', 'plugin-tomcat', 'plugin-services'].each { plugin ->
        compile "org.grails:grails-$plugin:2.2.0.RC2"
    }
    bootstrap "org.codehaus.groovy:groovy-all:2.0.5"
}
  // Get hold of the grails-run-app task (which is created on the fly) and add a dependency to the copyDependencies task
project.gradle.afterProject { p, ex ->
    if (p == project) {
        project.tasks.addRule("Grails dependencies") { String name ->
            if (name.startsWith(grailsTaskPrefix)) {
                tasks.getByName(name).dependsOn(copyDependencies)
            }
        }
    }
}
  // Build and copy any dependent jar files...
task copyDependencies(type: Sync) {
    from project(':dependent-project').configurations.archives.allArtifacts.files
    into "$projectDir/lib"
}

Turns out all I needed to do was add the following and then the grails plugin deals with the dependencies for me…

compile project(':dependent-project')