Spring Boot可执行Jar启动失败求助:编译成功但运行报错
mvn clean install -Pdev打包的Jar无法启动,而spring-boot:repackage可以? 这个问题的核心在于Spring Boot可执行Jar的特殊结构要求,以及Maven默认打包和Spring Boot插件打包的本质差异:
1. Spring Boot可执行Jar的特殊规则
Spring Boot的可执行Jar不是普通的Java Jar,它采用了「嵌套Jar」的特殊结构——把应用代码和所有依赖Jar都打包进同一个文件里。为了让Spring Boot的自定义类加载器能正确读取这些嵌套的Jar,所有依赖Jar必须以未压缩的方式存储,这就是你报错里提到的"It has been compressed and nested jar files must be stored without compression"的根本原因。
2. mvn clean install -Pdev的问题所在
默认情况下,Maven的install目标只是执行了package阶段的普通打包逻辑:它会把你的代码编译、打包成一个普通Jar,这个过程中会对Jar内的所有文件(包括嵌套的依赖Jar)进行压缩。这种普通Jar完全不符合Spring Boot可执行Jar的规范,所以用java -jar启动时必然报错。
3. mvn package spring-boot:repackage -Pdev能解决问题的原因
spring-boot:repackage是Spring Boot Maven插件提供的专属目标,它的核心作用就是把普通Jar重新打包成符合Spring Boot规范的可执行Jar:
- 重新组织Jar内部结构,将依赖Jar放到特定目录下;
- 强制保证所有嵌套的依赖Jar以未压缩的方式存储;
- 注入Spring Boot的启动器类和自定义类加载器逻辑,让Jar可以直接通过
java -jar启动。
4. 优化方案:让mvn clean install自动生成可执行Jar
如果你不想每次都手动追加spring-boot:repackage命令,可以在pom.xml的Spring Boot Maven插件配置中,把repackage目标绑定到Maven的package阶段。这样每次执行mvn clean install -Pdev时,都会自动完成重新打包步骤:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
配置完成后,再执行mvn clean install -Pdev,生成的Jar就是可以直接启动的Spring Boot可执行Jar了。
内容的提问来源于stack exchange,提问作者Hassen

