如何将Java应用压缩为Minify JAR?Maven打包后能否生成该JAR?
Hey there! Let's tackle your Spring JAR compression problem step by step—since you're dealing with a 120MB JAR and Maven's default setup isn't cutting it, I've got some solid approaches for you, including how to generate a minified JAR with Maven.
Short answer: Absolutely. A "minified JAR" here refers to a JAR optimized by stripping unused code, obfuscating class/method names (where safe), compressing bytecode, and removing redundant resources. Maven has plugins that integrate directly with tools designed for this purpose, so you won't need to switch build tools.
Let's start with the most impactful techniques, ordered from easiest to implement to more advanced:
2.1 Optimize Your Dependencies First (Low-Hanging Fruit)
Often, a large JAR is bloated with unused dependencies. Before diving into compression:
- Run
mvn dependency:analyzeto identify unused dependencies and declared-but-unused imports. Remove any that aren't critical. - Exclude redundant transitive dependencies from your starters. For example, if you're using
spring-boot-starter-webbut don't need Tomcat, exclude it:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>
2.2 Use ProGuard for Minification & Obfuscation
ProGuard is the industry standard for Java code minification—it shrinks (removes unused code), optimizes (reduces bytecode size), and obfuscates (renames classes/methods to shorter names) your JAR. Here's how to integrate it with Maven:
Add this plugin to your pom.xml (adjust package names and rules to match your project):
<build> <plugins> <!-- Your existing Spring Boot/Maven JAR plugin here --> <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.6.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>proguard</goal> </goals> </execution> </executions> <configuration> <proguardVersion>7.2.1</proguardVersion> <options> <!-- Core compression rules --> <option>-allowaccessmodification</option> <option>-shrink</option> <!-- Remove unused code --> <option>-optimize</option> <!-- Optimize bytecode --> <option>-obfuscate</option> <!-- Rename classes/methods --> <!-- Critical: Keep Spring-related classes/annotations (Spring uses heavy reflection) --> <option>-keep @org.springframework.boot.autoconfigure.SpringBootApplication class *</option> <option>-keep @org.springframework.stereotype.Component class *</option> <option>-keep @org.springframework.web.bind.annotation.RestController class *</option> <option>-keepclassmembers class * { @org.springframework.beans.factory.annotation.Autowired *; @org.springframework.beans.factory.annotation.Value *; }</option> <!-- Keep your main application class --> <option>-keep class com.yourcompany.YourSpringApp { public static void main(java.lang.String[]); }</option> <!-- Preserve annotations and reflection metadata --> <option>-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault</option> </options> <injar>${project.build.finalName}.jar</injar> <outjar>${project.build.finalName}-minified.jar</outjar> <libraryjars> <path>${java.home}/lib/rt.jar</path> <path>${java.home}/lib/jce.jar</path> </libraryjars> </configuration> <dependencies> <dependency> <groupId>net.sf.proguard</groupId> <artifactId>proguard-base</artifactId> <version>7.2.1</version> <scope>runtime</scope> </dependency> </dependencies> </plugin> </plugins> </build>
Important Notes:
- Always test the minified JAR thoroughly—ProGuard can accidentally remove code used via reflection (common in Spring). Adjust the
-keeprules if you run into runtime errors. - If obfuscation causes issues (e.g., with logging or external APIs), disable it with
-dontobfuscateand rely only on shrinking/optimization.
2.3 Spring Boot-Specific Optimizations
If you're using Spring Boot, these tools can cut your JAR size drastically:
- Spring Boot Thin Launcher: This plugin separates your application code from dependencies, creating a tiny "thin" JAR (usually <5MB) that pulls dependencies at runtime from a Maven repository. Perfect for cloud deployments.
- JLink for Custom JRE: If your project uses Java 9+, use
jlinkto create a minimal JRE containing only the modules your app needs. Combine this with a minified JAR to reduce the total deployment size even more.
- After minification, you can still apply standard ZIP compression to the JAR (most tools like
zipor7zipcan shrink it further by 10-20%). - Compare sizes: Run
ls -lh target/*.jarto see the difference between your original JAR and the minified version. For a 120MB Spring JAR, you can easily get it down to 30-50MB with ProGuard and dependency cleanup.
内容的提问来源于stack exchange,提问作者kussart

