63

有人可以给我一个简单的 build.gradle 示例,说明如何指定不包含在运行时部署(war)中的仅编译时类。

由于“运行时”继承自“编译”,Gradle 似乎以错误的方式解决了这个问题。我无法想象在运行时我想要在编译时不想要的类的情况。但是,在许多情况下,我需要类在编译时生成我不希望在运行时部署的代码!

我已经浏览了臃肿的 gradle 文档,但找不到任何明确的说明或示例。我怀疑这可以通过定义“配置”并将其设置为 CompileJava 插件的类路径来实现 - 但文档不足以解释如何实现这一点。

4

11 回答 11

57

关于这个话题已经有很多讨论了,主要是这里,但没有明确的结论。

您走在正确的轨道上:目前最好的解决方案是声明您自己的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]
  }
}

通常这很好用。

于 2012-05-02T00:23:24.540 回答
12

如果你使用战争插件,providedCompile应该做的伎俩。但是,如果您需要将依赖项排除在jar中,则必须扩展该jar任务。下面是一个构建“fat jar”或“uber jar”(包含其依赖项的所有类的单个 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/

更新:

Gradle 2.12开始,定义仅编译依赖项的问题最终通过新的“copmpileOnly”配置以简单自然的方式解决:

dependencies {
    compileOnly 'javax.servlet:servlet-api:2.5'
}
于 2014-09-12T13:54:15.730 回答
9

我为我的项目设置解决了这个问题。我使用运行 gradle 插件 0.9.+ 和 gradle 1.11 的 Android Studio 主项目使用亚马逊广告和亚马逊应用内购买。它依赖于使用亚马逊设备消息(ADM)的库项目。

我的主要问题是我得到“RuntimeException:Stub!”的 ADM。错误。

1.)图书馆项目:正如他所说,Lukas 提出的“提供的配置”不起作用,所以我使用了 Richards 的方法,但是开箱即用的效果并不好。由于在 aar 文件的 ext_libs 文件夹中找不到该库,因此我不得不对其进行一些更改。Gradle 似乎将所有库打包在最终 aar 文件中的 libs 文件夹中。

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
}
于 2014-06-11T08:07:26.900 回答
6

运行时依赖项不是编译时依赖项是很常见的。另一种方式是一种相当特殊的情况,因此需要在 Gradle 中进行几行配置。我建议在Gradle 论坛中搜索provided.

听起来您真正追求的是为您的构建声明依赖项,而不是为编译类路径。这如何完成取决于如何调用所需的功能(Ant 任务、Gradle 任务/插件、构建脚本中的临时使用)。如果您提供有关您尝试做什么的更详细信息,我可以提供更具体的答案。

以下是 Gradle 用户指南中相关信息的一些链接:

于 2012-05-02T16:53:14.517 回答
6

如果你使用 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"
}
于 2013-09-09T13:36:49.257 回答
6

在 Gradle 2.12compileOnly中引入了配置。可以在此处找到介绍此功能的博客文章:

Gradle 最新特性:仅编译依赖项

请注意一个重要的副作用:

由于添加了“compileOnly”配置,“compile”配置不再代表所有编译时依赖项的完整图景。当需要在构建脚本或自定义插件中引用编译类路径时,应使用适当的源集的 compileClasspath 属性。

于 2016-03-30T08:28:41.040 回答
3

事实证明,他们在 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 Studio library.jar 的存在。这个想法插件似乎不适用于 Android 工作室。我猜他们有另一个用于将 gradle 与工作室同步的自定义插件。

于 2014-07-10T21:39:47.760 回答
2

我没有找到适用于 Android Studio 的解决方案,但这是我尝试过的:

在 android studio 中,我必须更新到 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

于 2014-03-12T09:08:16.067 回答
2

在 Android Studio 1.0 中执行以下操作:

android.libraryVariants.all { variant ->
    variant.outputs.each { output ->
        output.packageLibrary.exclude('libs/someLib.jar')
    }
}
于 2014-12-09T07:22:24.177 回答
0

OP 显然没有寻找 Android 的答案,但有些答案是针对 Android 的。所以我建议你看看这个页面:http ://tools.android.com/tech-docs/new-build-system

0.9.0 版引入了提供的范围。所以,只需使用

dependencies {
    provided "groupId:artifcatId:version"
}
于 2014-07-03T11:33:45.063 回答
0

我们不需要“提供”,尝试添加这个:

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

享受!

于 2014-04-24T22:31:43.490 回答