笔者的项目使用SpringBoot+gradle构建,多模块间有依赖关系。本文记录遇到的构建问题与对应的解决方案。
模型代码
本文使用的一个简单项目来说明问题,项目简介如下:
- 项目包含demo0和demo1两个子模块
- demo0 模块是一个Springboot项目,提供一个Car类型的bean
- demo1 模块依赖 demo0 模块,也是一个Springboot项目
- demo1 引入demo0 中Car类型的bean
代码地址:
- github: github.com/PeakSongBlo…
- gitee: gitee.com/peaksongblo…
相关文档
关键知识点
本文主要涉及到springboot的构建知识,需理解springboot为gradle构建量身定制的构建插件的功效,在gradle的构建中主要体现为 jar 和 bootjar的配置。
多项目结构依赖配置
- 在demo1的
dependencies中引入对demo0模块依赖
implementation(project(":demo0"))
- 在demo1的配置代码中设置对demo0的包扫描, 使得demo0中的bean生效
@ComponentScan("blog.peaksong.demo0")
@Configuration
class Config
额外的设置
如果是一般的项目,这样的设置已经足够,但是被依赖的demo0是一个Springboot的项目,由于SpringBoot自带的gradle插件,demo0中构建任务jar被取消,bootjar被默认启动,故而我们会遇到以下报错。
- 启动报错 Unresolved reference: demo0
22:45:32: Executing task ':demo1:classes'...
Starting Gradle Daemon...
Gradle Daemon started in 2 s 754 ms
> Task :demo0:compileKotlin UP-TO-DATE
> Task :demo0:compileJava NO-SOURCE
> Task :demo0:processResources NO-SOURCE
> Task :demo0:classes UP-TO-DATE
> Task :demo0:inspectClassesForKotlinIC UP-TO-DATE
> Task :demo0:jar SKIPPED
> Task :demo1:compileKotlin FAILED
e: C:\Users\PeakSong\IdeaProjects\juejin\juejin0\demo1\src\main\kotlin\blog\peaksong\demo1\Controller.kt: (3, 22): Unresolved reference: demo0
e: C:\Users\PeakSong\IdeaProjects\juejin\juejin0\demo1\src\main\kotlin\blog\peaksong\demo1\Controller.kt: (12, 32): Unresolved reference: Car
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':demo1:compileKotlin'.
> Compilation error. See log for more details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 26s
3 actionable tasks: 1 executed, 2 up-to-date
22:46:08: Task execution finished ':demo1:classes'.
demo1 Springboot构建,会将所有依赖的jar加到最终的jar中,所以我们可以使用java -jar 直接启动,但是从日志中,我们可以看出demo0的jar任务被跳过,这导致demo0最终没有以jar形式引入,故而报错。 使得项目正常启动,我们只需要启用demo0的jar任务即可。
在demo0的build.gradle.kts中,再次运行项目成功
tasks.jar {
enabled = true
}
- 构建失败
22:55:24: Executing task 'bootJar'...
> Task :demo0:compileKotlin UP-TO-DATE
> Task :demo0:compileJava NO-SOURCE
> Task :demo0:processResources NO-SOURCE
> Task :demo0:classes UP-TO-DATE
> Task :demo0:bootJarMainClassName
> Task :demo0:bootJar FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':demo0:bootJar'.
> Failed to calculate the value of task ':demo0:bootJar' property 'mainClass'.
> Main class name has not been configured and it could not be resolved
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1s
3 actionable tasks: 2 executed, 1 up-to-date
22:55:26: Task execution finished 'bootJar'.
根项目的bootJar运行失败,提示demo的bootJar任务启动时,没有找到一个启动的主类。这个时候有两种方式修复,一种是给demo0添加一个Demo0Application的类,被@SpringBootApplication修饰,这样根项目的BootJar可以正常通过;另一种方法是直接关闭demo0的bootjar。 在实际项目中,一般采用第二种方法。
tasks.bootJar {
enabled = false
}
总结
SpringBoot多模块依赖问题的构建 重点在于掌握Springboot自带插件对构建任务的设置。