如何在Maven打包WAR时仅包含直接依赖,排除传递依赖?
问题:Maven打包WAR时仅保留直接依赖、排除所有传递依赖
背景与需求
我正在将一个单体遗留企业应用从Ant迁移至Maven,已梳理Ant构建所用依赖并创建对应POM文件。当前核心需求是:打包生成WAR文件时,仅将POM中列出的直接依赖纳入WEB-INF/lib目录,排除所有传递依赖。
问题复现示例
以batik-all依赖为例,配置如下:
<!-- batik-all依赖配置 --> <dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-all</artifactId> <version>1.16</version> <type>pom</type> </dependency>
执行命令 mvn clean -U install 后,仅该依赖就会引入约30个传递依赖。
已尝试但无效的方案
我曾给依赖添加全局排除规则,但传递依赖仍会被打包,配置如下:
<dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-all</artifactId> <version>1.16</version> <type>pom</type> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
限制条件
- 不想使用maven-war-plugin的
<packagingExclusions>标签,因为需要排除的传递依赖多达近80个,维护成本高; - 当前使用Maven版本3.3.9,maven-war-plugin固定版本3.2.2。
解决方案
方案1:标记直接依赖为provided+用dependency-plugin手动复制
这是最省心的方案,通过provided scope阻断传递依赖,再手动复制指定依赖到WEB-INF/lib:
- 给所有直接依赖添加
<scope>provided</scope>:
<dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-all</artifactId> <version>1.16</version> <type>pom</type> <scope>provided</scope> </dependency>
provided scope的依赖不会被Maven自动引入传递依赖,也不会默认打包到WAR中。
- 配置maven-dependency-plugin,复制所有
provided依赖到WEB-INF/lib:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.1.2</version> <!-- 适配Maven 3.3.9的稳定版本 --> <executions> <execution> <id>copy-provided-deps</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <includeScope>provided</includeScope> <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> </configuration> </execution> </executions> </plugin> <!-- 保留原有的war插件配置 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> </plugins> </build>
方案2:在dependencyManagement中全局禁用传递依赖
如果不想逐个修改scope,可以在依赖管理模块中给每个直接依赖添加全局排除:
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-all</artifactId> <version>1.16</version> <type>pom</type> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <!-- 其他所有直接依赖都按此格式添加全局排除 --> </dependencies> </dependencyManagement>
之后在<dependencies>中引入依赖时,无需重复写exclusions,但需要给每个直接依赖都配置一次,适合依赖数量较少的场景。
方案3:用shade-plugin合并pom依赖为单个jar(不推荐)
针对batik-all这类pom类型的依赖,可以用shade-plugin将其合并成单个jar,避免传递依赖:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <includes> <include>org.apache.xmlgraphics:batik-all</include> </includes> </artifactSet> </configuration> </execution> </executions> </plugin>
这种方式可能引发类冲突,仅适合依赖结构简单的场景,不推荐用于复杂企业应用。
内容的提问来源于stack exchange,提问作者ֆքɨƈɛǟռɢɛʟ
相关产品推荐
相关产品推荐

