What's a good approach to setup a project with generated-sources (avro)?


(Ken Diep) #1

I am currently evaluating gradle for a new project that needs to deal with generated sources from avro. I have manage to set it up but I do think it can be improved.

rootDir\modules\simple-api - this project contains the avro schema and protocol files to be generated. The generated sources are created in the rootDir\build\simple-api\gen and it is being compiled from here. nothing special and all is good

rootDir\modules\simple-server - this project contains the implementation and it references the simple-api project.

This approach works and in the future if I have a complex server it may reference simple-foo-api and simple-bar-api, which can easily be referenced via associated project. There are a couple of issues with this (to me at least); 1. The generated idea module will have a reference to the *-api, which i want to exclude, which I’ll dig through the docs shortly. 2. Having 2 project, seems to me like it’s a big of a mess (but that’s just me)

Aside, from the above, I am trying to layout the project much like the apiAndImpl project (which I kind of prefer) in the samples folder and the folder layout is per below;

rootDir\modules\simple\src\api-- contains the avro files rootDir\modules\simple\src\main – contains the implementation files

building the project will yield two jars, simple-api.jar which contains the generated avro files and a simple.jar which just contains the implementation. First, a minor idea issue, this module will have a reference to the “simple\resources\api” folder, which doesn’t exist. Now a confusing and difficult issue with referencing the simple-api.jar.

I have strict requirement to have a local ivy repo that is committed along with the source code (no generated-code) to svn. this local ivy repo is located at “rootDir/lib/repo”.

Because I needed a temp location to store the generated jars, I’ve created temporary ivy repo in “rootDir/idealibs” this hold all the *-api jars so that idea can reference it.

  1. in the main build.gradle file I have the repositories declared as
repositories {
    //local ivy repo that is committed to svn
    ivy {
        url "file://${rootDir}/lib/repo"
        layout "pattern", {
          artifact "[organisation]/[module]/[artifact]-[revision].[ext]"
          //ivy "[organisation]/[module]/[module]-ivy-[revision].xml"
        }
    }
    //temporary ivy repo for idea
    ivy {
        url "file://${rootDir}/build/idealibs/"
        layout "pattern", {
          artifact "[organisation]/[module]/[artifact]-[revision].[ext]"
          ivy "[organisation]/[module]/[module]-ivy-[revision].xml"
        }
    }
}

the simple.gradle file that hook things together def generatedSourceDir = “${buildDir}/generated/sources/java” def generatedResourcesDir = “${buildDir}/generated/resources/api” def generatedClassesDir = “${buildDir}/generated/classes/api”

sourceSets {

api {

java {

srcDir generatedSourceDir

}

} }

dependencies {

apiCompile “org.apache.avro:avro:1.7.4”

apiCompile “org.apache.avro:avro-ipc:1.7.4”

apiCompile ‘org.codehaus.jackson:jackson-core-asl:1.8.8’

apiCompile ‘org.codehaus.jackson:jackson-mapper-asl:1.8.8’

compile sourceSets.api.output

runtime configurations.apiRuntime }

task generateSources(type: GenerateAvroTask) {

source = file(“src/api”)

outputDirectory = file(generatedSourceDir) }

sourceSets.api { set ->

def compileTask = task("${set.name}Compile", type: JavaCompile) {

source generatedSourceDir

destinationDir file(generatedClassesDir)

classpath = set.compileClasspath

dependsOn generateSources

}

def jarTask = task("${set.name}Jar", type: Jar) {

baseName = baseName + “-$set.name

from generatedClassesDir

dependsOn compileTask

}

artifacts {

archives jarTask

} }

uploadArchives {

repositories {

ivy {

url “file://${rootDir}/build/idealibs/”

layout “pattern”, {

artifact “[organisation]/[module]/[artifact]-[revision].[ext]”

ivy “[organisation]/[module]/[module]-ivy-[revision].xml”

}

}

} }

because the simple-api contains the bean and data transfer objects, I’d like to reuse this jar in other projects, such as simple-foo, in which case I want to reference it as compile: ‘com.foo:simple-api:1.0’, which however resulted in an error as it can’t reference the jar.

running the uploadArchives task do yield files in the idealibs\com.foo folder; simple-api-1.0.jar, simple-1.0.jar and simple-ivy-1.0.jar. I do think this is where the problem is. it should have created idealibs\com.foo\simple and idealibs\com.foo\simple-api. Please advise, while I run off to read the ivy-publish module some more.

Thanks,


(Luke Daley) #2

So your immediate problem is how to reference the ‘simple-api’ jar in other projects?


(Ken Diep) #3

in short, yes.


(Luke Daley) #4

This section of the user guide may help you…

http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:project_jar_dependencies

Let me know if that doesn’t clear it up.