我在从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/
答案 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
任务。一旦进行了上述更改(同时保留了启动插件),一切就开始起作用。