Proguard混淆Spring Boot Jar后无法运行的问题求助
问题:Spring Boot混淆Jar运行时嵌套Jar压缩异常
通过Maven构建Spring Boot可执行Jar并使用Proguard混淆后,运行Jar时抛出异常,提示嵌套Jar文件被压缩,而Spring Boot要求嵌套Jar必须以未压缩形式存储。
异常堆栈信息
Exception in thread "main" java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/commons-lang3-3.4.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:285) at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:260) at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:248) at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:237) at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:103) at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:87) at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:72) at org.springframework.boot.loader.Launcher.launch(Launcher.java:49) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
使用的Maven Proguard插件配置
<plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.3.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <proguardVersion>6.0.3</proguardVersion> <injar>${project.build.finalName}.jar</injar> <outjar>${project.build.finalName}.jar</outjar> <obfuscate>true</obfuscate> <options> <option>-dontshrink</option> <option>-dontoptimize</option> </options> <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude> <libs> <lib>${java.home}/lib/rt.jar</lib> <lib>${java.home}/lib/jce.jar</lib> <lib>${java.home}/lib/jsse.jar</lib> </libs> </configuration> <dependencies> <dependency> <groupId>net.sf.proguard</groupId> <artifactId>proguard-base</artifactId> <version>6.0.3</version> </dependency> </dependencies> </plugin>
解决方案
方法1:修改Proguard配置,禁止压缩嵌套Jar
Proguard默认会压缩输出Jar中的所有条目,包括BOOT-INF/lib下的嵌套Jar,这违反了Spring Boot的加载要求。需要添加配置禁止压缩这些嵌套Jar,同时保留目录结构:
在proguard-maven-plugin的<options>节点中添加以下配置:
<option>-keepdirectories</option> <option>-dontcompress BOOT-INF/lib/*.jar</option>
或者在proguard.cfg文件中加入这两行:
-keepdirectories -dontcompress BOOT-INF/lib/*.jar
-keepdirectories确保Proguard保留Jar中的目录结构,-dontcompress指定不对BOOT-INF/lib下的所有Jar文件进行压缩,完全匹配Spring Boot加载器的要求。
方法2:调整插件执行逻辑
确保Spring Boot Maven插件先完成可执行Jar的构建,再由Proguard进行混淆处理:
- 保持现有插件执行顺序(Spring Boot插件默认在
package阶段先执行,Proguard插件随后执行)。 - 若需避免Proguard覆盖原始Jar,可将
<outjar>设置为不同文件名,后续再通过Spring Boot插件重新打包,但更简便的方式是直接使用方法1的配置解决压缩问题。
验证方案
执行mvn clean package重新构建Jar,运行Jar文件确认异常消失。也可手动解压Jar,检查BOOT-INF/lib下的Jar文件是否为未压缩状态(未压缩的Jar文件大小与原始依赖Jar一致,解压工具不会显示压缩标识)。
内容的提问来源于stack exchange,提问作者Saad Nisar
相关产品推荐
相关产品推荐

