Spring Boot 多项目 Gradle --> 主类名未配置,无法解析
Posted
技术标签:
【中文标题】Spring Boot 多项目 Gradle --> 主类名未配置,无法解析【英文标题】:SpringBoot with multi-project Gradle --> Main class name has not been configured and it could not be resolved 【发布时间】:2019-06-05 16:21:19 【问题描述】:我的项目结构如下:
RootProject
├── lib
└── src
└── main
└── java
└── ...
├── test-project
└── src
└── main
└── java
└── ...
└── build.gradle
我尝试使用 Gradle best practices 进行多项目构建,因此我在单个 build.gradle 文件中描述了整个构建过程。
“RootProject”只是一个没有任何代码的根项目,其唯一目的是为其子项目提供一个 build.gradle:“lib”和“test-project”。
“test-project”是一个使用“lib”作为编译依赖的SpringBoot项目(微服务)。
我常见的 build.gradle 如下所示:
plugins
id 'java'
id 'org.springframework.boot' version '2.1.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.6.RELEASE'
allprojects
repositories
jcenter()
subprojects
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.springframework.boot'
group = 'com.xxx.yyy'
version = '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
project(":lib")
apply plugin: 'java-library'
dependencies
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
bootJar enabled = false
jar enabled = true
project(":test-project")
apply plugin: 'java'
dependencies
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
implementation project(":lib")
implementation ('mysql:mysql-connector-java')
“lib”和“test-project”都已成功构建。但是,当我尝试在根项目上执行“bootJar”任务(应该触发所有子项目上的“构建”任务)时,我收到以下错误:
Main class name has not been configured and it could not be resolved
有什么想法吗?
【问题讨论】:
如果主类在你的lib项目中,而spring-boot插件在test-project中,你需要在插件中配置主类。只是为了确定:主类上有@SpringBootApplication注解? 【参考方案1】:多项目构建最佳实践简介
当你说:
我尝试遵循 Gradle 最佳实践进行多项目构建,因此我在单个 build.gradle 文件中描述了整个构建过程。
我不认为这实际上是一个好的做法,这也不是你提到的the guide 真正推荐的做法。
在指南介绍中:
虽然每个子项目都可以在完全隔离的情况下配置自己 其他子项目,子项目共享共同点是很普遍的 特征。然后通常最好在它们之间共享配置 项目,因此相同的配置会影响多个子项目。
=> 实际上,子项目之间共享的共同特征应该在根项目构建的中心位置进行配置。
在指南的后面(在this section 中)有一个示例,其中在根项目脚本中定义了子项目特定配置,但示例描述中有一个注释:
所有的构建逻辑都在根项目的构建脚本中。(2)
(2):我们在这里这样做,因为它使布局更容易一些。 我们通常将项目特定的东西放入各个项目的构建脚本中。
关于您的问题
我假设您的 lib
项目是一个普通的“简单”java lib 项目(没有 Spring 或 SpringBoot 依赖项),test-project
是包含 SpringBoot 应用程序类的项目(特别是 @SpringBootApplication
主应用程序类)。
按照上述最佳实践,您应该拥有三个不同的项目构建脚本:
root project
: 用于定义子项目中的通用配置共享(java插件配置、存储库、共享依赖等...)
lib
project :此 lib 项目的特定配置(java-library 插件,特定依赖项,...)
没有理由将spring-boot
插件应用到这个子项目,这实际上是你的错误“找不到主类”的原因
如果这个项目依赖于 Spring-core 模块,你可以简单地应用 io.spring.dependency-management
插件(在这种情况下,在根项目构建中应用这个依赖插件是有意义的,在两个子项目中使用相同的 Spring 版本)
test-project
project:Spring Boot应用相关配置(SpringBoot插件和依赖)
示例
根项目构建
ext
slf4jVersion = "1.7.25"
subprojects
apply plugin: "java"
// if both subprojects share some Spring related dependencies, apply the Spring `io.spring.dependency-management` here.
group = 'com.xxx.yyy'
version = '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories
jcenter()
'lib' 项目构建
plugins
id 'java-library'
dependencies
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
// lib dependencies
'test-project' 构建
plugins
id "org.springframework.boot" version "2.1.1.RELEASE"
apply plugin: 'io.spring.dependency-management'
dependencies
implementation project(":lib")
implementation('org.springframework.boot:spring-boot-starter-web')
testImplementation('org.springframework.boot:spring-boot-starter-test')
implementation ('mysql:mysql-connector-java')
// ...
编辑根据您的评论:如果 lib
项目需要 Spring Data 相关的东西,请按如下方式应用 io.spring.dependency-management
(查看更多详细信息 in Spring reference guide)
plugins
id 'java-library'
id "org.springframework.boot" version "2.1.1.RELEASE" apply false
apply plugin: 'io.spring.dependency-management'
dependencyManagement
imports
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
dependencies
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// lib dependencies
【讨论】:
"lib" 是一个具有处理 JPA 的“通用”(例如可重用)代码的库。因此,“lib”需要在 Spring 中具有依赖关系,但它并不是可执行的。第二个项目(“test-project”)引用(“lib”)作为编译依赖项,并打算执行(spring boot) 正如我在回答中所说,如果您在lib
中需要一些与 Spring 相关的部门,您只需应用 io.spring.dependency-management
插件,而不是“spring-boot”插件。我更新了我的答案。
"dependencyManagement" 部分丢失,现在可以编译。谢谢
关注点分离的优秀答案。并将(仅)抽象的 SLF4J 抽象 jar 放在“较低的项目”中。谢谢。以上是关于Spring Boot 多项目 Gradle --> 主类名未配置,无法解析的主要内容,如果未能解决你的问题,请参考以下文章
多模块 Gradle 项目 - 从 Spring-Boot 1.5 迁移到 2.1
Spring boot 和 Gradle 多模块项目,无法正确加载依赖项
Eclipse(STS) 导入本地 spring boot (gradle)多项目
Spring Boot gradle 多模块项目未解决的引用错误