Building multiple jars per project


(j serup) #1

In a project I have two source folders: “src” and “model”. I need to build a separate jar for each folder which works fine with:

apply plugin: 'java'
sourceSets {
 main {
  java {
   srcDir 'src'
  }
 }
    model {
  java {
   srcDir 'model'
  }
 }
  }
  task modelJar(type: Jar) {
 from sourceSets.model.output
 classifier = 'model'
 customName = 'model.jar'
}

Now to the problem. I have a class A in “src” which have a dependency on a class B in “model”. Therefore the classes in “model” must be available before building the classes in “src”.

Is it possible to introduce a build order for source folders in a project?

I have tried to swap the above folders in the sourceSets and I have also tried to use “dependsOn” when bulding the extra jar but it does not solve the problem. Any suggestions?

EDIT:

Adding this:

sourceSets.main.java.srcDirs 'model'

fixes the compile error but as a result the default jar also contains the model code which I don’t want.


(Peter Niederwieser) #2
dependencies {
  compile sourceSets.model.output // add classes/resources dirs
  // OR
  compile modelJar.outputs.files // add Jar
}

In both cases, the necessary task dependencies will be inferred automatically.


(j serup) #3

Thanks. It also works using the approach described here:

http://gradle.1045684.n5.nabble.com/How-do-I-add-a-second-source-set-to-compile-and-jar-td2641199.html

but your suggestion seems simpler. Why do you write “//OR” in the above snippet? Currently I need both and it appears to work.

I also need a test.jar so I have extended it to:

sourceSets {
 main {
  java {
   srcDir 'src'
  }
 }
 model {
  java {
   srcDir 'model'
  }
 }
 test {
  java {
   srcDir 'test'
  }
 }
}
  task modelJar(type: Jar) {
 from sourceSets.model.output
 classifier = 'model'
 customName = 'model.jar'
}
  task testJar(type: Jar) {
 from sourceSets.test.output
 classifier = 'test'
 customName = 'test.jar'
}
  dependencies {
 compile sourceSets.model.output
  compile modelJar.outputs.files // add model Jar
 compile testJar.outputs.files // add test Jar
}

but I get:

“Circular dependency between tasks. Cycle includes [task ‘:compileTestJava’, task ‘:testJar’].”

If I remove “compile testJar.outputs.files” and pass the task testJar on the commandline it works.


(Peter Niederwieser) #4

Why do you write “//OR” in the above snippet? Currently I need both and it appears to work.

You shouldn’t need both, as they are variations of the same thing (get the model classes on the compile class path of the main code).

but I get: “Circular dependency between tasks. Cycle includes [task ‘:compileTestJava’, task ‘:testJar’].” If I remove “compile testJar.outputs.files” and pass the task testJar on the commandline it works.

You don’t need that line, because you don’t want your test classes on the compile class path of your main code. It wouldn’t even work because it contradicts having the main classes on the compile class path of the test code, which is something that you do want (and is already set up for you by the Java plugin).

Just to be clear, ‘dependencies.compile’ means the compile dependencies of the main code. There’s also ‘dependencies.testCompile’ and ‘dependencies.modelCompile’ (and likewise for ‘runtime’).