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

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

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

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

Ответ 1

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

Вы на правильном пути: в настоящее время лучшим решением является объявление вашей собственной конфигурации 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]
  }
}

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

Ответ 2

Если вы используете военный плагин, 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'
}

Ответ 3

Я понял это для моей настройки проекта. Я использую 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:[email protected]'
    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
}

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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

Ответ 7

Оказывается, они добавили "предоставленную" конфигурацию в 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 со студией.

Ответ 8

Я не нашел решение для 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

Ответ 9

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

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

Ответ 10

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

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

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

Ответ 11

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

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

dependencies {
    provided "groupId:artifcatId:version"
}