这两个问题的出现场景是,你打包完一个SpringBoot、Maven项目,上传Jar包到服务器运行的时候遇到的。也算是比较经典的两个问题了,如果你在打包项目的时候,很容易遇到,这篇文章就是用来一劳永逸地解决它们。
1、问题出现
1.1、Jar包运行:没有主清单属性
解决方案
其实这个问题主要是在IDEA打包环节出现了问题,当我们对打包好的jar包进行解压以后会发现有一个MANIFEST.MF文件,此文件就是jar运行时要查找的清单目录。
主清单数据,就是我们要运行的主类即程序入口,缺少主清单属性,就不知道从哪开始运行。
因此我们需要对项目进行配置,指定程序入口。
我们需要在POM文件中引入:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
spring-boot-maven-plugin
是一个Spring Boot
插件,用于简化Spring Boot项目的构建和打包。它可以自动化地创建可执行的JAR文件,包括一个嵌入式的Tomcat服务器,这样你就可以直接运行你的应用程序,而不需要先安装Java或Tomcat。
1.2、Springboot打包 Jar 出现 java.lang.NoClassDefFoundError 的问题
Caused by: java.lang.ClassNotFoundException: AAA
Caused by: java.lang.NoClassDefFoundError: AAA
Caused by: java.lang.reflect.InvocationTargetException
java.lang.IllegalArgumentException: Unable to create serializer “com.esotericsoftware.kryo.serializers.FieldSerializer” for class:com.xxx.yyy.BBB
这个问题的出现其实还是跟打包插件有关系,我不赞同这篇文章的说法 《【Springboot】打包 Jar 出现 java.lang.NoClassDefFoundError 的问题》
,这篇文章说和引入依赖本身有问题。大家可以试试这个文章的解决方案。
解决方案
谈到maven的打包,我们需要知道我们平时打包的插件有两种:
maven-jar-plugin
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin>
maven-assembly-plugin
[推荐!]
这个插件的主要作用是帮助你构建一个包含所有依赖的JAR文件。
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>true</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin>
前者为原始jar包,类似于maven-jar
打包里面的origin-jar
,后者with-dependencies
为包含pom中费provided依赖的jar包,如果线上环境未提供这些依赖,就得使用with-dependencies
的jar包。
解决:
使用 maven-assembly-plugin
上传了原始jar包,而生产环境中没有AAA,所以BBB中调用显示no class found,改为上传with-dependicies
包后,程序正常运行.
我在打包好jar包以后,上传了服务器,在服务器运行jar包的时候同时遇到了上面两个问题,最后我的pom文件是这么写的:
<build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>true</appendAssemblyId> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
其实就是综合了SpringBoot运行的插件spring-boot-maven-plugin
和maven打包插件maven-assembly-plugin
两种方式结合使用,大家可以直接复制!