如何在Gradle中定义编译时*仅*类路径?

时间:2012-05-01 23:56:56

标签: compilation classpath gradle

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

Gradle似乎已经采用了错误的方法,因为'运行时'继承自'编译'。我无法想象在运行时我想要在编译时不想要的类的情况。但是,在很多情况下我需要类在编译时生成代码,我不希望在运行时部署它们!

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

11 个答案:

答案 0 :(得分:56)

关于这个主题已经有很多讨论,主要是here,但不是明确的结论。

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

通常情况下效果很好。

答案 1 :(得分:11)

如果您使用 war 插件,providedCompile应该可以解决问题。 但是,如果您需要将依赖项排除在 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'
}

答案 2 :(得分:9)

我想出了我的项目设置。 我使用带有gradle插件0.9。+ with gradle 1.11的Android Studio运行 主要项目使用亚马逊广告和亚马逊inapp购买。 它取决于使用亚马逊设备消息(ADM)的图书馆项目。

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

1。)图书馆项目: Lukas提出的“提供的配置”不起作用,正如他所说的那样,所以我使用了理查兹的方法,然而开箱即用的方法并不好用。我不得不改变它,因为我在aar文件的ext_libs文件夹中找不到lib。 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
}

答案 3 :(得分:6)

拥有不是编译时依赖项的运行时依赖项是很常见的。反过来说是一个相当特殊的情况,因此在Gradle中需要几行配置。我建议在Gradle forum搜索provided

听起来你真正想要的是为 build 声明依赖关系,而不是为了编译类路径。如何完成这取决于如何调用所需的功能(Ant任务,Gradle任务/插件,从构建脚本临时使用)。如果您提供有关您要执行的操作的更详细信息,我可以提供更具体的答案。

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

答案 4 :(得分:6)

如果您使用WAR插件,可以使用此example

中的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"
}

答案 5 :(得分:5)

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

Gradle latest feature: Compile only dependencies

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

  

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

答案 6 :(得分: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工作室存在library.jar。这个想法插件似乎不适用于Android工作室。我猜他们有另一个自定义插件用于同步gradle和studio。

答案 7 :(得分: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

答案 8 :(得分:2)

在Android Studio 1.0中执行此操作:

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

答案 9 :(得分:0)

我们不需要&#34;提供&#34;,尝试添加此内容:

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

享受!

答案 10 :(得分:0)

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

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

dependencies {
    provided "groupId:artifcatId:version"
}