Gradle多项目构建在测试期间看不到内部依赖性

时间:2019-11-13 14:04:04

标签: java gradle

我在从Gradle 4迁移到5的大型多项目构建中遇到问题,并在较小,更简洁的构建中复制了该问题以演示该问题。

我在构建中有2个项目。一个是另一个使用的依赖项(基本库)。

demo (root project)
|- build.gradle
|
|--- demo-web
|---|- build.gradle
|
|--- demo-dependency
|---|- build.gradle

演示网络摘要:build.gradle

...
dependencies {
    implementation project(':demo-dependency')
    ...
}
...

依赖项目定义了一个在Web项目DownstreamThing中使用的类。

Web项目尝试使用它来构造自己的对象,但是在根项目级别上进行构建时,它会失败。

> ./gradlew build
> Task :demo-web:test

com.example.demo.ThingTest > testThing FAILED
    java.lang.NoClassDefFoundError at ThingTest.java:12
        Caused by: java.lang.ClassNotFoundException at ThingTest.java:12

ThingTest.java

    @Test
    public void testThing() {
        DownstreamThing t =  new DownstreamThing(); //line 12, ClassNotFoundException
        assertTrue(t != null);
    }

我在Gradle 4中对此没有任何问题,但在Gradle 5中没有问题。为什么在测试任务中找不到依赖项?

示例的完整来源在这里:https://bitbucket.org/travelsized/gradle-problem/src/master/

3 个答案:

答案 0 :(得分:0)

请尝试编译而不是像下面这样的实现: 依赖项{     编译项目(':demo-dependency')     ... }

也许DownstreamThing类没有进行单元测试。

答案 1 :(得分:0)

我相信他之所以会收到该异常,是因为您已将Spring Boot插件应用于demo-dependency项目。该插件的作用是将jar文件重新打包到需要特殊类加载器才能加载内容的胖jar中。

您仍然可以在没有插件的依赖项项目中使用Spring Boot依赖项(例如,启动器)。因此,如果可以,只需将其删除。

如果有特定原因,您将需要保留原始jar文件,以便将其用作实际依赖项。对于Spring Boot 1.5.x,您可以使用以下方法做到这一点:

bootRepackage {
    classifier = "boot"
}

bootJar {
    enabled = true
}

但是请注意,我不认为Spring Boot 1.5与Gradle 5及更高版本(目前是6.0)完全兼容,因此您可能需要降级Gradle或升级Spring Boot。

答案 2 :(得分:0)

BjørnVester的回答使我指出了正确的方向。 spring-boot插件导致jar任务出错。我需要确保在启用jar任务时禁用了bootJar任务的依赖关系。

在Gradle版本和Spring Boot插件之间进行配置更改以使其在升级中丢失。

以前,我可以为jar启动后指定一个分类器:

bootRepackage  {
    classifier = 'exec'
}

现在,我需要启用和禁用适当的任务:

bootJar {
    enabled = false
}

jar {
    enabled = true
    archiveBaseName = "demo-dependency"
}

在较大的项目中,我以前有一个jar任务,它指定了archiveBaseName,但是没有明确地使它能够覆盖bootJar任务。一旦进行了上述更改(同时保留了启动插件),一切就开始起作用。