TL;DR I expected the dependencies of a module to be built into its .jar, but they don't appear to be.
I'm using Gradle to build a project. I have two subprojects, app
(an Android module) and tests
(a Java module), as created by IntelliJ.
Since I want to use the classes defined in app
in the contents of tests
, I've added the appropriate dependency. Inspired by this answer, I've got the following setup:
app/build.gradle:
...
task jarTask(type: Jar) {
baseName ="${project.archivesBaseName}"
from android.sourceSets.main.java
}
configurations {
jarConfiguration
}
artifacts {
jarConfiguration jarTask
}
tests/build.gradle
...
dependencies {
...
testCompile project(path: ':app', configuration: 'jarConfiguration')
}
However, one of the classes in app
imports org.json.JSONObject
. Since this is provided by the Android SDK, app
can find it fine - but when I try to run tests, I get (in :tests:compileTestJava
) "package org.json does not exist". However, if I update tests/build.gradle to be
...
dependencies {
...
testCompile project(path: ':app', configuration: 'jarConfiguration')
testCompile 'org.json:json:20090211'
}
(See here) then the tests run correctly.
This wasn't what I expected - if a .jar doesn't package up its dependencies, then any project which depends on that .jar must also explicitly depend on the transitive dependencies - wouldn't this cause dependency definitions to rapidly increase?
I came across the concept of a "fatJar" here and here, which seems to be synonymous with a "jar with dependencies" - but changing my app/build.gradle to read
...
task jarTask(type: Jar) {
baseName ="test-${project.archivesBaseName}"
from android.sourceSets.main.java
}
task fatJar(type: Jar) {
baseName = project.name + "-all"
from {configurations.compile.collect {it.isDirectory() ? it : zipTree(it)}}
with jarTask
}
configurations {
jarConfiguration
}
artifacts {
jarConfiguration fatJar
}
still gives an error that package org.json does not exist
. This appears to be because org.json
is not explicitly called out as a dependency in the app/build.gradle file. With the following app/build.gradle, my project built and ran tests as expected:
...
dependencies {
...
compile 'org.json:json:20090211'
}
task jarTask(type: Jar) {
baseName ="${project.archivesBaseName}"
from android.sourceSets.main.java
}
task fatJar(type: Jar) {
baseName = project.name + "-all"
from {configurations.compile.collect {it.isDirectory() ? it : zipTree(it)}}
with jarTask
}
configurations {
jarConfiguration
}
artifacts {
jarConfiguration fatJar
}
(Note that if you just want the fatJar task, you can simply set from files({configurations.compile.collect {it.isDirector() ? it : zipTree(it)}}, android.sourceSets.main.java)
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