I simply wish to build a jar with another configuration and add it to my artifacts (with a classifier). Let’s say I have project foo:
// foo/build.gradle
apply: 'java'
configurations {
h2
// does NOT extend compile, since I wish to use alternate dependencies that are incompatible with my compile dependencies
}
// Hadoop 1 and Hadoop 2 are binary incompatible, although this project's code is source-compatible with both for compilation
dependencies {
compile "org.apache.hadoop:hadoop-core:1.2.1"
h2 "org.apache.hadoop:hadoop-common:2.3.0"
}
task h2Jar(type: Jar) {
configuration = configurations.h2 // This doesn't seem right. How do I specify this?
from sourceSets.main.output // Is this right?
classifier = "h2" // this jar should have a classifier to distinguish it
}
artifacts {
archives h2Jar
}
It really seems like it should be this straightfoward, but I know that it’s not.
Just to be clear, I wish to have both jars built, i.e. a foo-$version.jar and a foo-$version-h2.jar, and have these both added to the ivy information. In the ivy, each artifact should have its respective dependencies, e.g. foo-$version.jar depends on the Hadoop 1 jars and foo-$version-h2.jar depends on the Hadoop 2 jars.
I’m looking through the documentation, and I think I may need to add another sourceSet and set its compileClasspath to be the h2 configuration, but I’m not sure exactly how to specify it. The h2 sourceSet would still point to src/main, since I would be compiling the same code for both the compile and h2 configurations.
@carlo.if, I don’t think your problem is that much related.
If I understand the problem correctly, the biggest complexity is having 2 separate artifacts in an ivy module (xml), each having different set of dependencies? If that’s the case then here are your options:
the most natural approach is avoid sticking both of those artifacts in a single ivy module, e.g. create a separate subproject for the other jar
ivy provides ways to have different artifacts have different set of dependencies. It is implemented via configurations. E.g. artifact is declared with configuration ‘h2’, the ‘h2’ conf has also some dependencies declared. Then, the consumers that wish to consume this artifact must declare the target configuration explicitly. For example, some consumer wants to have a compile dependency on this ‘h2’ artifact (I made up the group/name/version coordinates):
The critical part is setting the ‘target configuration’ at the dependency declaration. This instructs the Gradle’s resolution engine to download only artifacts and dependencies attached to ‘h2’ configuration. This is pretty unconventional and hence by default I recommend option #1. However, depending on your exact scenario (e.g. who/how consumes the artifact) #2 might be what you need. BTW. In gradle build files, by default you don’t have to specify the ‘target configuration’ of the dependencies because a configuration named “default” is used.
Here was my solution. This builds one code base (under src/main) twice, using two sets of compilation dependencies; produces both a regular jar artifact and an artifact with a -h2 classifier; and produces ivy that refers to both artifacts and has the correct dependencies for both.