Зависимости, не скопированные в банку (в Gradle)

TL; DR Я ожидал, что зависимости модуля будут встроены в его .jar, но они не выглядят.

Я использую Gradle для создания проекта. У меня есть два подпроекта: app (модуль Android) и tests (модуль Java), созданный IntelliJ.

Поскольку я хочу использовать классы, определенные в app в содержимом tests, я добавил соответствующую зависимость. Вдохновленный этим ответом, у меня есть следующая настройка:

Приложение/build.gradle:

...
task jarTask(type: Jar) {
    baseName ="${project.archivesBaseName}"
    from android.sourceSets.main.java
}

configurations {
    jarConfiguration
}

artifacts {
    jarConfiguration jarTask
}

Тесты/build.gradle

...
dependencies {
    ...
    testCompile project(path: ':app', configuration: 'jarConfiguration')
}

Однако один из классов в app импортирует org.json.JSONObject. Так как это обеспечивается Android SDK, app может найти его в порядке, но когда я пытаюсь запустить тесты, я получаю (в :tests:compileTestJava) "пакет org.json не существует". Однако, если я обновляю тесты /build.gradle, чтобы быть

...
dependencies {
    ...
    testCompile project(path: ':app', configuration: 'jarConfiguration')
    testCompile 'org.json:json:20090211'
}

(см. здесь), тогда тесты выполняются правильно.

Это не то, что я ожидал - если .jar не упаковывает свои зависимости, то любой проект, который зависит от этого .jar, также должен явно зависеть от транзитивных зависимостей - не будет ли это причиной определения зависимостей быстро увеличить?

Ответ 1

Я столкнулся с концепцией "fatJar" здесь и здесь, который, кажется, синонимом "jar with dependencies" - но изменение моего приложения /build.gradle для чтения

...
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
}

все еще дает ошибку, что package org.json does not exist. Это связано с тем, что org.json явно не вызывается как зависимость в файле app/build.gradle. В следующем приложении /build.gradle мой проект построил и запускал тесты, как ожидалось:

...
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
}

(Обратите внимание: если вы просто хотите задачу fatJar, вы можете просто установить from files({configurations.compile.collect {it.isDirector() ? it : zipTree(it)}}, android.sourceSets.main.java)