问题 Gradle'提供'对Java插件的依赖


我正在尝试编译几个WAR文件,所有这些都依赖于一个通用的JAR模块。然而,在我的Gradle构建中,我似乎无法像使用Java插件那样获得“提供”之类的依赖项。

我的编译看起来像这样:

apply plugin: 'java'
configurations{
    providedCompile
}

dependencies {
    compile module("org.springframework.amqp:spring-amqp:${springAmqpVersion}")
    compile module("org.slf4j:slf4j-api:${slf4jVersion}")
    compile module("org.slf4j:slf4j-ext:${slf4jVersion}")

    providedCompile "javax.servlet:servlet-api:${servletApiVersion}"

    runtime module("org.slf4j:jcl-over-slf4j:${slf4jVersion}")
    runtime module("org.slf4j:jul-to-slf4j:${slf4jVersion}")
    runtime module("org.slf4j:log4j-over-slf4j:${slf4jVersion}")

    sourceArchives module("org.springframework.amqp:spring-amqp:${springAmqpVersion}:sources")
    sourceArchives module("javax.servlet:servlet-api:${servletApiVersion}:sources")
}


sourceSets {
    main { compileClasspath += configurations.providedCompile }
}

但是,最后一位是获得异常的地方。我已经尝试在运行时依赖项扩展它之后将servlet-api(由Tomcat提供)添加到配置中,或者只是将其作为编译模块放入,然后将其从运行时依赖项中删除。

我尝试了几种不同的修改依赖关系的方法,最接近的结果是:

newRuntime = configurations.runtime.minus(configurations.providedCompile)
configurations.runtime = newRuntime

然而,最后一位将生成变量 newRuntime 具有适当的依赖项,但是当我尝试将变量重新分配回运行时配置时,它会抛出“找不到属性异常”

我在Gradle的错误跟踪上发现了很多关于这个确切问题的讨论:摇篮-784

然而,主要的导致是来自Spring,他使用Maven和他们的gradle构建,我不熟悉。

我在SO上找到的最有希望的链接,但不幸的是我无法让这些例子工作: 提出问题 值得注意的是Stack Overflow问题显示了最有希望的一行:

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

此行不会像其他尝试一样给出错误,但似乎提供的Compile(我提供的版本)依赖项实际上并未放在编译类路径上,因为尝试编译时会出现类路径错误。


7093
2017-09-06 13:45


起源

值得注意的是 forums.gradle.org/gradle/topics/... 似乎建议只设置编译以扩展提供的配置。这似乎是有效的,但逻辑上没有意义,因为运行时也扩展编译? - Chris Lefevre
可能重复 如何在Gradle中定义编译时*仅*类路径? - xsveda


答案:


我不是100%关注你的消息,但提供的编译仅允许'war'插件。

apply plugin: 'war'

dependencies {
  // others go here
  providedCompile "javax.servlet:javax.servlet-api:${servletVersion}"
}

在“war”步骤中,不包括servlet jar。


5
2017-09-06 13:52



这就是我实际想要的概念。但是要注意我在没有war插件的情况下为providedCompile添加了一个配置。我试图在WAR JAR中获得与WAR相同的功能。有些人建议使用WAR插件,打开jar.enabled,然后删除WAR。这是我们目前正在做的事情,但是所提供的依赖关系是在之后创建的JAR中。 - Chris Lefevre
我会说:不要打击工具。 - Natan Cox


你添加了一个 providedCompile 配置,但你没有做任何事情。因此它不会在任何类路径上。要将配置放在主编译类路径上,您可以执行以下操作:

sourceSets.main.compileClasspath += configurations.providedCompile

同样,将它放在测试编译类路径上:

sourceSets.test.compileClasspath += configurations.providedCompile

5
2017-09-06 15:59



我试过这个,意识到我确实忘了把它放到测试中,但我仍然得到:java.lang.NoClassDefFoundError引起:java.lang.ClassNotFoundException寻找那个JAR文件。有什么我应该知道的gradle解决方案,我发现它提供了编译扩展?该解决方案似乎正在运行,JAR不在生成的WAR中,并且所有测试都正在正确编译。 - Chris Lefevre
没有更多信息,我不能说问题是什么。这个解决方案适合我。如果你这样做 configurations.compile.extends configurations.provided,我认为所提供的依赖关系将最终在战争中(没有额外的反措施)。 - Peter Niederwieser


您可以使用  范围内的'jar'模块和 providedCompile 内部'战争'模块。

战争 providedCompile 范围将覆盖jar的  范围。


3
2018-01-23 15:30