Как определить путь к компиляции-времени * только * class в Gradle?

354
50

Может кто-нибудь, пожалуйста, дайте мне простой пример build.gradle того, как я могу указать классы времени компиляции, которые не включены в развертывание во время выполнения (война).


Gradle кажется, что это неправильно, так как "runtime" наследуется от "компиляции". Я не могу представить ситуацию, когда я бы хотел, чтобы классы во время выполнения не захотели во время компиляции. Тем не менее, есть много обстоятельств, когда мне нужны классы для генерации кода во время компиляции, которые я не хочу развертывать во время выполнения!


Я вспахал раздутую документацию gradle, но не могу найти никаких четких инструкций или примеров. Я подозреваю, что это может быть достигнуто путем определения "конфигурации" и установки его как пути к классам плагина CompileJava, но документация не подходит для объяснения того, как этого добиться.

спросил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
1
Решение
330

Было много дискуссий по этой теме, главным образом здесь, но не ясный вывод.


Вы на правильном пути: в настоящее время лучшим решением является объявление вашей собственной конфигурации provided, которая будет включать в себя только зависимости от компиляции и добавить к вашему пути к компиляции:

configurations{
provided
}

dependencies{
//Add libraries like lombok, findbugs etc
provided '...'
}

//Include provided for compilation
sourceSets.main.compileClasspath += [configurations.provided]

// optional: if using 'idea' plugin
idea {
module{
scopes.PROVIDED.plus += [configurations.provided]
}
}

// optional: if using 'eclipse' plugin
eclipse {
classpath {
plusConfigurations += [configurations.provided]
}
}


Как правило, это хорошо работает.

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
155

Если вы используете военный плагин, providedCompile должен сделать трюк.
Однако, если вам нужно исключить зависимости из числа jar, вам придется расширить задачу jar.
Ниже приведен пример построения "толстой банки" или "uber jar" (единственная банка, которая включает в себя все классы его зависимостей), за исключением отметок provided:


configurations {
provided
compile.extendsFrom provided
}

dependencies {
provided "group.artifact:version"
compile "group.artifact:version"
}

jar {
dependsOn configurations.runtime
from {
(configurations.runtime - configurations.provided).collect {
it.isDirectory() ? it : zipTree(it)
}
}
}


Кредит: http://kennethjorgensen.com/blog/2014/fat-jars-with-excluded-dependencies-in-gradle/

Update:


По состоянию на Gradle 2.12 проблема определения компиляции только зависимостей окончательно решена простым и естественным образом с помощью новой конфигурации "copmpileOnly":


dependencies {
compileOnly 'javax.servlet:servlet-api:2.5'
}

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
141

Я понял это для моей настройки проекта.
Я использую Android Studio с плагином gradle 0.9. + С gradle 1.11
В основном проекте используются объявления amazon и покупки amazon inapp.
Это зависит от проекта библиотеки, использующего обмен сообщениями амазонных устройств (ADM).


Моя главная проблема была в ADM, где я получил "RuntimeException: Stub!". ошибка.


1.) Проект библиотеки:
"Предоставленная конфигурация", предложенная Лукасом, не работает, как заявил ему, поэтому я использовал подход Ричардса, который, однако, не работал также из коробки. Мне пришлось немного изменить его, так как я не мог найти lib в папке ext_libs файла aar. gradle, кажется, упаковывает все библиотеки в папке libs в финальном aar файле.


android.libraryVariants.all { variant ->
variant.packageLibrary.exclude( 'libs/amazon-device-messaging-1.0.1.jar' )
}

2.) Проект приложения:
Здесь работает подход с "предоставленной конфигурацией".


configurations{
provided
}
dependencies {
compile 'fr.avianey:facebook-android-api:+@aar'
compile files('ext_libs/amazon-ads-5.3.22.jar')
compile files('ext_libs/in-app-purchasing-1.0.3.jar' )
provided files('ext_libs/amazon-device-messaging-1.0.1.jar')
}

android.applicationVariants.all {
variant -> variant.javaCompile.classpath += configurations.provided
}

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
118

Если вы используете плагин WAR, вы можете использовать providedCompile, как в этом примере


dependencies {
compile module(":compile:1.0") {
dependency ":compile-transitive-1.0@jar"
dependency ":providedCompile-transitive:1.0@jar"
}
providedCompile "javax.servlet:servlet-api:2.5"
providedCompile module(":providedCompile:1.0") {
dependency ":providedCompile-transitive:1.0@jar"
}
runtime ":runtime:1.0"
providedRuntime ":providedRuntime:1.0@jar"
testCompile "junit:junit:4.11"
moreLibs ":otherLib:1.0"
}

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
118

Общепринято иметь зависимости от времени выполнения, которые не зависят от времени компиляции. Другой способ - довольно частный случай, и для этого требуется несколько строк конфигурации в Gradle. Я предлагаю найти Gradle форум для provided.


Похоже на то, что вы действительно после этого объявляете зависимости для своей сборки, а не для пути класса компиляции. Как это делается, зависит от того, как вызывается требуемая функциональность (Ant task, Gradle task/plugin, ad-hoc use from build script). Если вы предоставите более подробную информацию о том, что вы пытаетесь сделать, я могу предоставить более конкретный ответ.


Вот несколько ссылок на релевантную информацию в руководстве пользователя Gradle:


ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
109

В Gradle 2.12 была введена конфигурация compileOnly. Сообщение в блоге, в котором представлены эти функции, можно найти здесь:


Gradle последняя функция: скомпилировать только зависимости


Обратите внимание на один важный побочный эффект:


В результате добавления конфигурации "compileOnly" конфигурация "компиляции" больше не представляет собой полную картину всех зависимостей времени компиляции. При необходимости ссылаться на путь компиляции classpath в скриптах сборки или пользовательских плагинах, вместо этого следует использовать соответствующий исходный код свойство compileClasspath.


ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
91

Оказывается, они добавили "предоставленную" конфигурацию в gradle плагин android 0.8.0, но это не совсем работает. Он автоматически добавляет предоставленные библиотеки в путь компиляции, но также включает их в окончательный aar/apk.


Что сработало для меня, было решение, предоставленное @lukas-hanaceck, но путем изменения имени из "предоставленного" на любое другое пользовательское имя. В моем случае это проект библиотеки, который является зависимым от моего окончательного проекта приложения для Android. Это суть того, что сработало для меня.


configurations {
providedlibs
}

dependencies {
providedlibs files('provided/library.jar')
}

libraryVariants.all {
variant -> variant.javaCompile.classpath += configurations.providedlibs
}


Он компилируется отлично, и предоставленный /library.jar не включен в окончательный apk. Единственная проблема, с которой я столкнулся, - это отметить студию Android о существовании library.jar. Плагин идеи, похоже, не работает для студии Android. Я предполагаю, что у них есть другой настраиваемый плагин для синхронизации gradle со студией.

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
77

В Android Studio 1.0 сделайте следующее:


android.libraryVariants.all { variant ->
variant.outputs.each { output ->
output.packageLibrary.exclude('libs/someLib.jar')
}
}

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
77

Я не нашел решение для Android Studio, но это то, что я пробовал:


В студии android мне пришлось обновить до версии 0.5. +


в gradle/gradle-wrapper.properties заменить


distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-rc-3-bin.zip

по


distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip

во всех моих build.gradle замените


buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.+'
}
}

по


buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
}
}

и в библиотеке, которую я хотел использовать при условии


configurations {
provided
}

//put applicationVariants in case it is apply plugin: 'android' and not apply plugin: 'android-library'
android.libraryVariants.all {
variant -> variant.javaCompile.classpath += configurations.provided
}

dependencies {
provided files('ext_libs/amazon-device-messaging-1.0.1.jar')
}


и в конце он не работает, кажется, что он работает для jar, но не для aar или apk, как указано здесь https://groups.google.com/forum/#!topic/adt-dev/WIjtHjgoGwA

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
45

OP явно не искал ответа на Android, но некоторые ответы специфичны для Android. Поэтому я предлагаю вам посмотреть эту страницу: http://tools.android.com/tech-docs/new-build-system


Версия 0.9.0 представила предоставленную область. Итак, просто используйте


dependencies {
provided "groupId:artifcatId:version"
}

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
45

Нам не нужно "предоставлено", попробуйте добавить это:


android.libraryVariants.all { variant ->
variant.packageLibrary.exclude( 'ext_libs/amazon-device-messaging-1.0.1.jar' )
}

Наслаждайтесь!

ответил(а) 2021-01-19T19:36:04+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема