Java学习之SpringBoot项目打包成可执行jar
- "XXX中没有主清单属性"
- "找不到主类"
- Caused by: java.util.ServiceConfigurationError: cn.bjca.footstone.sword.json.spi.JsonMapperFactory: cn.bjca.footstone.sword.json.impl.jackson.JsonMapperFactoryImpl Unable to get public no-arg constructor
- Windows Java环境变量配置未生效,显示版本不对
- Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.Versioned
- 执行测试
- 参考链接
“XXX中没有主清单属性”
-
原因分析
打包后的jar文件中的MANIFEST.MF缺少项目启动项,即没有Main-Class和Start-Class
-
解决方案
在项目pom.xml文件中添加插件spring-boot-maven-plugin
<!-- 引入SpringBoot插件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.2.5.RELEASE</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> <configuration> <classifier>spring-boot</classifier> <mainClass> <!-- 自定义程序启动类 --> </mainClass> </configuration> </execution> </executions> </plugin>
“找不到主类”
-
其他类似错误
springboot无法启动,java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
-
原因分析
起初以为是引入的插件不对,应该引入maven-jar-plugin,最后发现不是,而是引入的spring-boot-maven-plugin没有定义mainClass,或者定义的不对。
-
试错方案
指定packaging方式为jar(默认就是jar),但为了保险起见。
<packaging>jar</packaging> <!-- 试错依赖 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass> <!-- 自定义启动类 --> </mainClass> </manifest> </archive> </configuration> </plugin>
Caused by: java.util.ServiceConfigurationError: cn.bjca.footstone.sword.json.spi.JsonMapperFactory: cn.bjca.footstone.sword.json.impl.jackson.JsonMapperFactoryImpl Unable to get public no-arg constructor
-
原因分析
运行环境JDK版本与打包编译JDK版本不一致导致。
本地允许环境是JDK11,而编译环境是JDK8,所以在IDEA中启动正常访问,但是打包为jar时本地执行提示类似上述错误。
-
解决方案
通过将 JAVA_HOME 环境变量从 JDK 11 更改为 JDK 8 来解决。
Windows Java环境变量配置未生效,显示版本不对
-
原因分析
本地同时安装了多版本JDK,也配置了多个系统变量,类似下面:
但是本地执行
java -version
却显示默认jdk11,原因是:如果检查配置时,java -version 显示的版本不对、配置未生效,检查系统环境变量Path,发现开头有: C:\Program Files\Common Files\Oracle\Java\javapath C:\ProgramData\Oracle\Java\javapath C:\Program Files\Common Files\Oracle\Java\javapath: 安装Java8时,Oracle会在path路径中添加C:\Program Files (x86)\Common Files\Oracle\Java\javapath,这个是自动配置;可以将其删除,因为我们自己会手动配置。 C:\ProgramData\Oracle\Java\javapath : 这个目录下就三个快捷方式:java.exe, javaw.exe, javaws.exe。在使用的过程中(比如J2EE项目运行)会把按照配置的 JAVA_HOME 路径加载java.exe、javaw.exe、javaws.exe,并在某一默认的路径(Windows电脑一般是 C:\ProgramData\Oracle\Java\javapath\)下生成以上三个文件的快捷方式。而在改变 JAVA_HOME 的时候,这三个文件的快捷方式仍然是之前的快捷方式,所以就会有问题了。
-
解决方案
把Path的配置顺序调整一下,把 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; 放到开头:
%JAVA_HOME%\bin; %JAVA_HOME%\jre\bin; C:\ProgramData\Oracle\Java\javapath\
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.Versioned
-
其他类似错误
java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/MismatchedInputException
-
原因分析
SpringBoot框架中引入jackson相关依赖,而本身引入的模块对jackson做了shade操作,导致打包成可执行jar项目执行时,找不到相关类,从而报错。
-
解决方案
抽取出公用代码,重新建个工程autoconfigure存放,然后保持提供给项目使用的模块不变,继续做shade操作。
但是需要打包成jar的项目不引入做shade操作的模块,而是引入新建的那个autoconfigure工程。
执行测试
-
编译打包
# 编译安装到本地 mvn clean install -DskipTests # 启动 java -jar xxxx.jar