How to build multiple artifacts from the same sources?


(robert) #1

Hello,

I try to use Gradle on an ant-based Java project. We produce a war file and four jar files. These jar files use some of the classes that also go in the war file, e.g., the reset password utility jar uses some of the database access classes and the user classes.

I can build the war file just fine. How do I specify that I also want to build these jar files?

I looked into multi-project builds but I cannot put these jar files in separate source directories cause they need classes from the war’s sources. Also, during transition from ant to gradle I’d like to keep the directory structure as is.

Any pointers?

Thanks,

Robert


(René Groeschke) #2

Hi Robert, I think in your scenario you should split up your sources by defining different sourceSets. SourceSets can be depend on each other and declaring a jar out of the sourceSet is quite simple. Have a look in the userguide at http://www.gradle.org/docs/current/userguide/java_plugin.html#sec:source_sets to find more details about that.

Hope that helped.

cheers, René


(robert) #3

Thanks, René.

I got it working now, but I don’t understand why or how it should really look. My build.gradle:

sourceSets {
    // ...
      myJar {
        java {
            srcFiles = files("src/com/...", "src/com/...")
        }
    }
}

This gets me a warning about defining dynamic properties. I’ve tried sources, source, and others, but no luck. http://www.gradle.org/docs/current/userguide/java_plugin.html does only mention ‘srcDirs’ which don’t really work for me cause I only want to include certain files.

Hence I added this:

compileMyJarJava {
    dependsOn "someGeneratedCode"
    source = files("src/com/...", "src/com/...") // same list as above
}

My jar task looks like this:

task myJar(type: Jar) {
    outputs.files "bin/myJar.jar"
    inputs.files sourceSets.myJar.output
    destinationDir file("bin")
    archiveName = "myJar.jar"
    from sourceSets.myJar.output
}

This works, but…

Is it better to define the source files in the sourceSets and if so, how do I do that? Is this very un-gradle-ish and how could I improve it? Any other comments?

Thanks,

Robert


(Peter Niederwieser) #4

You get a warning because there is no ‘srcFiles’ property. Instead you’d use ‘srcDirs’ together with ‘include’ and/or ‘exclude’. See the Gradle Build Language Reference for an example.


(robert) #5

Thanks, Peter.

I am now using

sourceSets {

// …

myJar {

java {

srcDirs = [“src”, “generated/src”]

srcDirs(“src”) {

include \

“com/me/my/product/Foo.java”,

“com/me/my/product/Bar.java”

}

srcDirs(“generated/src”) {

include \

“com/me/my/product/Generated.java”

}

}

}

}

It’s a little weird that it insists on the backslash after the include if I don’t want to place the included file on the same line but I can live with that.


(Peter Niederwieser) #6

Where did you get this include syntax from? I don’t think it will work. It should look like this:

sourceSets {
    myJar {
        java {
            srcDirs = ["src", "generated/src"]
            include "com/me/my/product/Foo.java"
            include "com/me/my/product/Bar.java"
            include "com/me/my/product/Generated.java"
        }
    }
}

The ‘’ in your code is needed because in Groovy (and other languages with optional semicolons), end-of-line also means end-of-statement.


(robert) #7

From http://www.gradle.org/docs/current/javadoc/org/gradle/api/tasks/util/PatternFilterable.html#include(java.lang.String...) and trial and error and ‘unzip -l’ on the resulting jar file.

Thanks for the pointer regarding the line endings.


(Peter Niederwieser) #8

Specifying includes/excludes per source directory isn’t currently supported. At best, your syntax will (accidentally) have the same effect as the official syntax shown above.


(robert) #9

Ok, thanks; I’ve changed it to use multiple includes.