Есть
Module 1 и
Module 2, оба зависят от модуля
Common. Зависимости от сторонних библиотек в модулях пересекаются.
Зависимости Common (файл
common/build.gradle):
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
compile 'org.apache.logging.log4j:log4j-core:2.0-rc2'
}
Module-2 (файл
module-2/build.gradle):
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
compile 'org.apache.logging.log4j:log4j-core:2.0-rc2'
compile project(':common')
}
Module-1 (файл
module-1/build.gradle):
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
compile 'org.apache.logging.log4j:log4j-core:2.0-rc2'
compile 'com.google.guava:guava:17.0' // её нет в Common
compile project(':common')
}
Задача: создать jar файлы для Module-1 и Module-2 со всеми
необходимыми зависимостями внутри, которые можно было бы запускать таким образом:
java -jar module-1.jar.
Первая попытка: сделать таску jar, отвечающую за итоговый файл, одинаковой для всех трех модулей:
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
//настройка manifest'a опущена
}
Вышеприведенный способ работает, но в jar файл
module-1.jar (и в
module-2.jar) дважды попадает пересечение зависимостей для Module-1 и Common, итого размер файла равен:
SIZE( src_module1 + 2 (dep_module1 ∩ dep_common) + ( dep_module1 \ dep_common) )
Вторая попытка: исключить из таски
jar модуля
Common файлы библиотек:
jar {
//from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
В итоге в
common.jar попадают только class файлы модуля
Common , как следствие, в файл
module-1.jar зависимости архивируются только один раз, уже хорошо.
Но возникает проблема: в случае, если у Common есть какая-то зависимость, а у Module-1 её нет, на уровне Module-1 придется описывать все необходимые зависимости Common, что неприемлимо.
Третья попытка: вернуть Common к шагу 1, а содержимое результатируещего jar описать вручную всеми зависимостями, исключая их пересечение Пример для
Module-1: jar {
// из зависимостей добавляем только ту, которая в названияя содержит common
from { configurations.compile.collect { it.toString().contains("common") ? zipTree(it) : false } }
// тут нужно подключить 'com.google.guava:guava:17.0'
}
Этот вариант показался правильнее, но труден для синтаксического описания.
Вопрос 1. Как указать в качестве источника
from для таски
jar
a) модуль проекта (код в примере выше - ущербен);
b) сторонюю библиотеку.
Вопрос 2. Существуют ли правильное решение данной задачи?