如何用Maven从单仓编译的可执行JAR中排除无关类
解决方法:用Maven Shade Plugin生成仅含必要依赖的可执行JAR
问题根源
你当前使用的maven-assembly-plugin自带的jar-with-dependencies描述符,会无脑打包项目里所有编译类和全部依赖,不会自动筛选主类实际需要的内容。另外你的pom里还有个小问题:两个Profile的ID都是Tool1,第二个应该改成Tool2,否则Maven会识别错误。
解决方案:换用Maven Shade Plugin
Maven Shade Plugin的minimizeJar功能可以分析主类的依赖树,只保留直接/间接用到的类(包括项目内部类和第三方依赖)。同时需要调整依赖范围,避免把测试类(比如JUnit)打包进去。
修改后的完整pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.tools</groupId> <artifactId>tools</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Tools</name> <description>Tools we use</description> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> <!-- 标记为测试依赖,不会打包进可执行JAR --> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> </dependency> <!-- More dependencies... --> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> </plugins> </build> <properties> <maven.compiler.source>11</maven.compiler.source> <!-- 和plugin配置统一为11 --> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <profiles> <profile> <id>Tool1</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.5.1</version> <!-- 指定插件版本 --> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>Tool1</finalName> <outputDirectory>bin</outputDirectory> <minimizeJar>true</minimizeJar> <!-- 开启精简模式 --> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.tools.Tool1</mainClass> <!-- 指定主类 --> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>Tool2</id> <!-- 修正重复的ID --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.5.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>Tool2</finalName> <outputDirectory>bin</outputDirectory> <minimizeJar>true</minimizeJar> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.tools.Tool2</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <!-- More profiles... --> </profiles> </project>
使用方式
运行对应Profile生成精简JAR:
- 生成Tool1:
mvn package -PTool1 - 生成Tool2:
mvn package -PTool2
注意事项
- 如果你的代码使用反射加载类,
minimizeJar的静态分析可能会漏掉这些类,需要手动在插件配置里添加filters规则保留它们 - 建议统一编译版本(原pom里plugin配置11,但properties里是1.8,已经帮你改成统一11了)
内容的提问来源于stack exchange,提问作者Thomas W
相关产品推荐
相关产品推荐

