如何使用ProGuard优化.war文件及运行proguard.sh报错问题咨询
问题原因
报错是因为你仅获取了ProGuard的源码,未执行编译构建操作,官方文档提到的lib目录是构建完成后才会生成的产物目录,源码初始状态不存在该目录。
解决步骤
第一步:完成ProGuard源码构建
- 进入你下载的ProGuard项目根目录:
cd /home/myusername/proguard - 确认当前Java环境版本为Java 8,避免构建失败:
java -version
如果输出不是Java 8版本,可通过以下命令切换默认JDK:sudo update-alternatives --config java
选择对应openjdk-8-jdk的选项即可。 - 执行构建命令生成lib目录:
./gradlew build
构建完成后即可看到项目根目录下生成lib目录,包含所需的proguard.jar文件,此时再运行bin/proguard.sh就不会再报jar找不到的错误。
第二步:使用ProGuard优化war包
ProGuard无法直接处理war归档文件,需要先解压再处理其中的Java字节码文件,操作流程如下:
- 解压原始war包到临时目录:
unzip your-application.war -d war-temp - 编写ProGuard配置文件(如
proguard-war.cfg),核心配置项参考:
注:以下配置为基础模板,你需要根据你应用的技术栈补充对应的keep规则,避免反射调用的类/方法被移除或混淆导致应用运行异常
# 输入:要优化的类目录和依赖jar -injars war-temp/WEB-INF/classes -injars war-temp/WEB-INF/lib/*.jar(!META-INF/MANIFEST.MF) # 输出目录 -outjars optimized-output # 依赖的Java运行时库,根据你实际的JDK路径调整 -libraryjars /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar -libraryjars /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar # 基础优化配置 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -optimizationpasses 5 -dontpreverify # 这里补充你需要保留的类规则,比如Spring相关类、Servlet接口实现类等 -keep public class * extends javax.servlet.http.HttpServlet -keep public class * extends org.springframework.web.servlet.DispatcherServlet -keep @org.springframework.stereotype.Controller class * { *; } -keep @org.springframework.stereotype.Service class * { *; } -keep @org.springframework.stereotype.Component class * { *; } -keepclassmembers class * { @org.springframework.beans.factory.annotation.Autowired *; @org.springframework.beans.factory.annotation.Value *; }
- 执行ProGuard处理:
bin/proguard.sh @proguard-war.cfg - 把优化后的产物替换回临时目录对应的位置:
首先把optimized-output目录下生成的类文件替换到war-temp/WEB-INF/classes,生成的jar文件替换到war-temp/WEB-INF/lib - 重新打包为优化后的war包:
cd war-temp && zip -r ../optimized-app.war *
注意事项
- 所有通过反射调用的类、方法、字段都必须在配置文件中添加keep规则,否则运行时会抛出类不存在、方法不存在等异常
- ProGuard仅处理Java字节码,war包内的静态资源(JS、CSS、图片、HTML等)需要使用对应前端压缩工具单独优化
- 优化完成后建议先在测试环境部署验证功能正常,再投入生产使用
内容的提问来源于stack exchange,提问作者user5507535
相关产品推荐
相关产品推荐

