使用 Spring Boot 从 Gradle 多模块项目构建的 Jar 不起作用

Posted

技术标签:

【中文标题】使用 Spring Boot 从 Gradle 多模块项目构建的 Jar 不起作用【英文标题】:Jar built from Gradle multi-module project with Spring Boot doesn't work 【发布时间】:2021-08-03 16:47:33 【问题描述】:

我创建了 spring-boot gradle 多模块项目,它由 3 个模块组成:控制器、服务、存储库。主文件位于 Controller-module 中,名为 MySpringBootApplication。

我可以构建这个项目(使用 gradle build)并且可以获得 jar 文件。但是在命令行中启动这个 jar 之后,我出现了下一个错误:

Error: Could not find or load main class com.epam.esm.config.MySpringBootApplication Caused by: java.lang.ClassNotFoundException: com.epam.esm.config.MySpringBootApplication.

为了修复这个错误,我将Main-Class 属性添加到主build.gradleMANIFEST.MF 文件中,但此操作没有帮助。那么有人可以帮忙吗?

主构建.GRADLE 文件

        plugins 
            id 'java'
            id 'io.spring.dependency-management' version '1.0.11.RELEASE'
            id 'org.springframework.boot' version '2.4.3'
            id 'application'
        
        
        group = 'com.myproject'
        version = 'snapshot-1.0.0'
        
        repositories 
            mavenCentral()
        
        
        bootJar 
            enabled = false
        
        
        jar 
            enabled = true
            manifest 
                attributes(
                        "Main-Class": "com.myproject.config.MySpringBootApplication")
            
        
       
     dependencies 
            implementation 'org.springframework.boot:spring-boot-starter'
            implementation group: 'org.springframework.boot', name: 'spring-boot-starter-parent', version: '2.4.3', ext: 'pom'
        
        
        
        test 
            useJUnitPlatform()
        
        
        
        subprojects 
            apply plugin: 'org.springframework.boot'
            apply plugin: 'io.spring.dependency-management'
            apply plugin: 'java'
        
            group = 'com.epam.esm'
            version = '1.0.0'
        
            repositories 
                mavenCentral()
            
            bootJar 
                enabled = false
            
        
            jar 
                enabled = true
            
            dependencies 
                implementation 'org.springframework.boot:spring-boot-starter'
                implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
                implementation 'org.springframework.boot:spring-boot-starter-hateoas'
                implementation 'org.springframework.boot:spring-boot-starter-actuator'
                implementation 'org.springframework.boot:spring-boot-starter-security'
                testImplementation 'org.springframework.boot:spring-boot-starter-test'
                implementation group: 'org.hibernate', name: 'hibernate-envers', version: '5.4.27.Final'
                implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
                implementation group: 'org.openidentityplatform.commons', name: 'json-web-token', version: '2.0.11'
                compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.18'
                annotationProcessor 'org.projectlombok:lombok'
                implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
                implementation group: 'org.springframework.boot', name: 'spring-boot-starter-parent', version: '2.4.3', ext: 'pom'
            
            test 
                useJUnitPlatform()
            
        

SETTINGS.GRADLE

    rootProject.name = 'module'
    include('repository', 'service', 'controller')

【问题讨论】:

你的应用模块应该有bootJar enabled =true 没用 【参考方案1】:

Spring Boot应用程序的可执行jar文件是由bootJar任务构建的,所以通过jar添加主类信息也不行。

bootJar 任务尝试创建一个可执行的 jar,并且 需要一个 main() 方法。因此,您需要禁用 bootJar 任务并启用 jar 任务(创建一个普通的 jar 而不是可执行的 jar) 仅适用于您的无可执行 jar 模块。

由于您是在subprojects 部分下完成的,所以controller 模块也会生成一个标准的jar。您可以为所有模块生成标准 jars,但不包括 controller 模块,如下所示:

subprojects 
    
    if (it.name != 'controller') 
        bootJar 
            enabled = false
        

        jar 
            enabled = true
        
    
    

此外,您必须删除下面的 jar 部分

 jar 
        enabled = true
        manifest 
            attributes(
                    "Main-Class": "com.myproject.config.MySpringBootApplication")
        
    

替换

bootJar 
    enabled = false

    bootJar 
        mainClassName = 'com.myproject.config.MySpringBootApplication'
    

参考

Creating a Multi Module Project

【讨论】:

你太棒了!!!!我有几天找不到答案,但您在发布问题后半小时内给出了答案。谢谢。

以上是关于使用 Spring Boot 从 Gradle 多模块项目构建的 Jar 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot 时使用 JaCoCo 代码覆盖率构建 Gradle 多项目失败

使用Spring Boot Gradle插件的多模块项目

多模块 Spring Boot 项目中的 Gradle 依赖插件

使用gradle BOM和spring-boot(多模块应用程序)哪种方式更好

无法集成测试 gradle 多模块 Spring-Boot-Application

Spring boot 和 Gradle 多模块项目,无法正确加载依赖项