Spring类型应用找不到主函数no main manifest attribute, in app.jar,spring-boot-maven-plugin的锅?

Spring类型应用找不到主函数no main manifest attribute, in app.jar,spring-boot-maven-plugin的锅?,第1张

Spring类型应用找不到主函数no main manifest attribute, in /app.jar,spring-boot-maven-plugin的锅?

这里写自定义目录标题

问题现象

错误1错误2 原因分析深入研究

spring-boot-maven-pluginmaven依赖的版本管理机制

parent指定为spring-boot-starter-parent在dependencyManagement中引入spring-boot-dependencies

问题现象 错误1

spring类型应用启动后报错,no main manifest attribute, in /app.jar

错误2

mvn build过程中,提示repackage failed

原因分析

大多数情况下,都是因为在spring应用的pom.xml中没有使用spring-boot-maven-plugin打包插件,或者插件的版本没有指定导致,需要在pom.xml里加入以下内容


    
            
                org.springframework.boot
                spring-boot-maven-plugin
                ${spring-boot.version}  //你的springboot的版本号是多少,这里就填多少
                
                    
                        
                            repackage  //如果你的项目的parent是spring-boot-starter-parent,executions这一段也可以省略,因为在parent中已经指定了。反之则不可省
                        
                    
                
            
    
 
深入研究 spring-boot-maven-plugin

spring-boot-maven-plugin是spring自带的一个用来打包的插件,其原理就是在mvn package的时候,将本应用自身的class,及他的依赖重新打包(repackage)成一个大的jar。只要安装指定版本jre,就可以通过java -jar xxx.jar运行,而不需要去系统的lib库中下载依赖,有兴趣看详情的可以看看spring-boot-maven-plugin原理,我们这里看下效果。

先建一个springboot的helloword项目,注意在pom里引入spring-boot-maven-plugin插件

public class CsdemoApplication {
    @RequestMapping("/")
    public String greeting() {
        return "Greeting!";
    }  
 
    public static void main(String[] args) {
        SpringApplication.run(CsdemoApplication.class, args);
    }
}

执行mvn clean package,在target目录下会生成一个jar文件和一个jar.original文件,original的还不到5K,其实这个是maven自带的打包工具对本工程自有代码进行打包的产物。而jar文件却有近26MB,这是spring-boot-maven-plugin对original进行repackage的产物。

把两个文件解压缩后对比,可以发现主要变化是jar里面多了一个lib文件夹,里面存储了本项目所依赖的所有jar。这个文件夹足足有25M,是导致整个jar包体积变大,以及为什么可以直接java -jar xxx.jar启动程序的原因。


写多了spring应用的同学估计注意到了,有时候可以省略${spring-boot.version}这一行,但是有时候就会报错,这又是为什么呢。

这个取决于你的项目的依赖关系,如果你的项目的parent是spring-boot-starter-parent(或其子项目),那么就可以在spring-boot-maven-plugin处省略version属性,mvn会自动去spring-boot-starter-parent中寻找相应的版本。


        org.springframework.boot
        spring-boot-starter-parent
        2.1.1.RELEASE
         

但如果你的项目的parent不是spring-boot-starter-parent(或其子项目),例如是继承于公司自己做的parent,那spring-boot-maven-plugin的version就必不可少,否则就会出现第一章中的错误。

maven依赖的版本管理机制

maven可以通过两种方式实现denpendencies模块中组件的版本统一管理,一种是整个项目parent指定为spring-boot-starter-parent,另一种是在dependencyManagement中引入spring-boot-dependencies,二者有一点点区别:

parent指定为spring-boot-starter-parent

如果你的项目的parent是spring-boot-starter-parent,那么在dependency中引入任何spring相关的starter时,均可以省略其版本号,原因就是在parent中已经引入了Spring Boot Dependencies,里面指定了大部分常用依赖的版本:

如果想在自己的应用中,修改某个依赖的版本,可以直接在properties中去指定:


     Fowler-SR2

如果要排除parent中默认使用的某个依赖,换成别的,可以按如下方式


      org.springframework.boot
       spring-boot-starter-data-rest
       
           
           
               io.lettuce
               lettuce-core
           
       


      redis.clients
       jedis

在dependencyManagement中引入spring-boot-dependencies

如果你的项目不是继承于spring-boot-starter-parent,而是通过dependencyManagement引入的sprintboot插件依赖,那么你依然可以在dependencies模块中省略各spring依赖的版本号,但是在build模块中就必须去指定版本号(比如前文所提到的spring-boot-maven-plugin就是在build模块下的)


    
        
            org.springframework.boot
            spring-boot-dependencies
            ${spring-boot.version}
            pom
            import
        
    

但这种方式,不能使用properties中直接去指定spring依赖的版本,而是需要在dependencyManagement里面的spring-boot-dependencies之前修改依赖的版本。例如同样修改Spring Data release train:


    
        
        
            org.springframework.data
            spring-data-releasetrain
            Fowler-SR2
            import
            pom
        
        
            org.springframework.boot
            spring-boot-dependencies
            ${spring-boot.version}
            pom
            import
        
    

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5719522.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存