Is there a way to construct a Gradle build file to force the test phase to use an earlier version of a dependency than the one used for compilation and and packaging?
I'm attempting to set up an HBase mini-cluster via HBaseTestingUtility to test my project; unfortunately, HBaseTestingUtility relies on an old version of Guava (14.0.1 seems to work), while the rest of my project uses 18.0. Here are excerpts of my build script, as-is (I'm also using the Gradle test-sets plugin by unbroken-dome to create two separate sets of tests):
plugins {
id 'org.unbroken-dome.test-sets' version '1.2.0'
}
apply plugin: 'java'
ext.verGuava = '18.0'
ext.verGuavaTEST = '14.0.1'
testSets {
testUnit { dirName = 'test/unit' }
testIntegration { dirName = 'test/integration' }
}
configurations {
provided
provided {
extendsFrom(compile)
}
testIntConf
testIntConf {
extendsFrom(provided)
resolutionStrategy {
force "com.google.guava:guava:${verGuavaTEST}"
forcedModules = ["com.google.guava:guava:${verGuavaTEST}"]
}
}
}
sourceSets {
main.compileClasspath += configurations.provided
testUnit.compileClasspath += configurations.provided
testUnit.runtimeClasspath += configurations.provided
testIntegration.compileClasspath += configurations.testIntConf
testIntegration.runtimeClasspath += configurations.testIntConf
}
dependencies {
provided "org.apache.hbase:hbase-client:${verHBase}"
provided "org.apache.hbase:hbase-common:${verHBase}"
compile "org.testng:testng:${verTestNG}"
testIntegrationCompile group:'org.apache.hadoop', name:'hadoop-common', version:"${verHadoop}", classifier: 'tests'
testIntegrationCompile group:'org.apache.hbase', name:'hbase-server', version:"${verHBase}"
testIntegrationCompile group:'org.apache.hbase', name:'hbase-server', version:"${verHBase}", classifier: 'tests'
testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop-compat', version:"${verHBase}"
testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop-compat', version:"${verHBase}", classifier: 'tests'
testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop2-compat', version:"${verHBase}"
testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop2-compat', version:"${verHBase}", classifier: 'tests'
testIntegrationCompile group:'org.apache.hadoop', name:'hadoop-hdfs', version:"${verHadoop}"
testIntegrationCompile group:'org.apache.hadoop', name:'hadoop-hdfs', version:"${verHadoop}", classifier: 'tests'
}
testUnit {
useTestNG()
logger.info "@@@ Classpath (UNIT testing): ${classpath.getFiles().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
logger.info "@@@ SystemProps (UNIT testing): ${System.getProperties().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
}
testIntegration {
useTestNG()
systemProperty "java.net.preferIPv4Stack", "true"
logger.info "@@@ Classpath (INTEGRATION testing): ${classpath.getFiles().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
logger.info "@@@ SysProps (INTEGRATION testing): ${System.getProperties().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
}
When I run a build via this script, I get the following output which seems to show that Guava 14.0.1 was added to the classpath for the testIntegration target, rather than replacing Guava 18.0:
@@@ Classpath (UNIT testing):
/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/18.0/cce0823396aa693798f8882e64213b1772032b09/guava-18.0.jar
@@@ Classpath (INTEGRATION testing):
/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/18.0/cce0823396aa693798f8882e64213b1772032b09/guava-18.0.jar
/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/14.0.1/69e12f4c6aeac392555f1ea86fab82b5e5e31ad4/guava-14.0.1.jar
This behavior is probably to be expected; the API indicates that ResolutionStrategy.force(...)
appends artifacts to the list to be considered.
How can I direct Gradle to eliminate Guava 18.0 from the classpath for the testIntegration target entirely?
I have tried changing the sourceSets
section to assign the classpaths using = rather than +=:
sourceSets {
...
testIntegration.compileClasspath = configurations.testIntConf
testIntegration.runtimeClasspath = configurations.testIntConf
}
This has the desired effect as far as eliminating Guava 18.0 (and retaining 14.0.1), but it seems to prevent Gradle from detecting the location of the testIntegration
source files, for some reason, so the testIntegration
tests are never compiled or executed.
I have also tried a few variations on purging Guava from the inherited configuration, such as the following:
configurations {
provided
provided {
extendsFrom(compile)
}
testIntConf
testIntConf {
extendsFrom(provided.copy {
exclude group:"com.google.guava", module:"guava"
})
resolutionStrategy {
force "com.google.guava:guava:${verGuavaTEST}"
forcedModules = ["com.google.guava:guava:${verGuavaTEST}"]
}
}
}
The above (and all other variations I've tried) do successfully eliminate the duplication of the Guava artifact in the classpath, but they seem to nullify the resolutionStrategy
, as the resolved artifact is always the newer version (18.0) even in testIntegration
.
To override the version of a transitive dependency in Gradle, exclude it from the declared dependency that pulls it in, and then explicitly declare the version that you prefer to use in your build.
When you specify a dependency in your build script, you can provide an exclude rule at the same time telling Gradle not to pull in the specified transitive dependency. For example, say we have a Gradle project that depends on Google's Guava library, or more specifically com.
This isn't necessary. The order inside the dependencies { } block is preserved. You are kind of right. Dependency ordering is preserved, but for example all compile dependencies will be before testCompile dependencies no matter of how you order them.
I was facing the same problem but simpler version. cause I am not differentiate the integration test and unit test. using this seems give the right guava dependency for test
configurations {
all{
resolutionStrategy {
force 'com.fasterxml.jackson.core:jackson-databind:2.4.4'
}
}
testCompile{
resolutionStrategy {
force 'com.google.guava:guava:14.0.1'
}
}
}
dependencies {
testCompile group: 'org.apache.hbase', name: 'hbase-testing-util', version: '1.2.4'
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With