• maven-shade-plugin - 解决 Jar 包冲突新思路


    打包是一个比较头疼的事情,默认 Maven 打包的结果只包含项目本身的代码,如果要执行代码,还得带上依赖。maven-shade-plugin插件就能够帮我们把项目依赖的包也打进最终文件。



    1、Maven 项目中三方依赖冲突的问题

    在现代 Java 开发中,Maven 项目打包是一个比较头疼的事情,我们经常需要处理项目的依赖管理和打包问题。

    在 Maven 项目中引入第三方组件时,这些三方组件的依赖可能与项目已有的依赖发生冲突。例如,如果第三方组件依赖的 HttpClient 版本是 4.5.x,而项目中已有的 HttpClient 版本是 3.1.x,就会产生以下两种情况:

    1. 用高版本覆盖低版本:如果使用第三方组件的高版本 HttpClient 覆盖项目中的低版本 HttpClient,有可能导致项目启动或运行失败。即使高版本兼容低版本,这种高风险的操作也是不被允许的;

    2. 排除高版本依赖:如果在第三方 Maven 依赖中排除了高版本的 HttpClient,使其使用项目中的低版本 HttpClient,可能会因为版本不一致导致第三方组件无法正常使用。

    在这样的情况下,我们如何保证在不影响项目原有依赖版本的前提下,正常使用第三方组件呢?这时可以考虑使用 Maven-Shade-Plugin 插件。这个插件可以将第三方组件及其依赖打包并重命名包名,以避免冲突,从而确保项目的稳定运行。


    2、maven-shade-plugin介绍

    maven-shade-plugin 是 Maven 官方网站中提供的一个插件,官方文档中定义其功能如下:

    This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

    简单来说就是将依赖的包在 Package 阶段一起打入 Jar 包中,以及对依赖的 Jar 包进行重命名从而达到隔离的作用。这里为了解决上面的问题我们主要使用第二个功能特性,使得相同依赖不同版本达到共存的目的。


    3、使用 maven-shade-plugin 解决 Jar 包冲突示例

    3.1、环境准备

    这里以 fastjson 库为例,模拟使用 maven-shade-pluginn 解决项目中不同版本共存的问题。假设原项目使用的是 1.1.15 版本的 fastjson:

    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.1.15version>
    dependency>
    

    并引入一个第三方依赖,该依赖使用 1.2.75 版本的 fastjson:

    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.2.75version>
    dependency>
    
    3.2、解决方案

    搭建一个新的模块 rename-dependencies,专门用于存放 1.2.75 版本的 fastjson 依赖。在 pom.xml 文件中添加该依赖,并配置 maven-shade-plugin:

    
    <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">
        <groupId>com.examplegroupId>
        <artifactId>rename-dependenciesartifactId>
        <version>1.0-SNAPSHOTversion>
        <modelVersion>4.0.0modelVersion>
    
        <dependencies>
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>fastjsonartifactId>
                <version>1.2.75version>
            dependency>
        dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.pluginsgroupId>
                    <artifactId>maven-shade-pluginartifactId>
                    <version>3.2.4version>
                    <executions>
                        <execution>
                            <phase>packagephase>
                            <goals>
                                <goal>shadegoal>
                            goals>
                            <configuration>
                                <filters>
                                    <filter>
                                        <artifact>*:*artifact>
                                        <excludes>
                                            <exclude>META-INF/*.SFexclude>
                                            <exclude>META-INF/*.DSAexclude>
                                            <exclude>META-INF/*.RSAexclude>
                                        excludes>
                                    filter>
                                filters>
                                <relocations>
                                    <relocation>
                                        <pattern>com.alibabapattern>
                                        <shadedPattern>shade.com.alibabashadedPattern>
                                    relocation>
                                relocations>
                            configuration>
                        execution>
                    executions>
                plugin>
            plugins>
        build>
    project>
    

    配置文件中的 relocations 部分通过重命名包名来隔离依赖。在这个例子中,将以 com.alibaba 开头的包名重命名为 shade.com.alibaba

    3.3、引入重命名后的依赖

    rename-dependencies 模块打包后,在原项目中引入:

    <dependency>
        <groupId>com.examplegroupId>
        <artifactId>rename-dependenciesartifactId>
        <version>1.0-SNAPSHOTversion>
    dependency>
    

    引入后,项目中的 fastjson 包名将会被重命名,确保不同版本可以共存。


    4、注意事项

    在实际操作中,可能会遇到引入依赖后找不到重命名的包的问题。此时,可以通过以下方法解决:

    • 将重命名模块从项目 Maven 中移除,然后重新引入。
    • 新建一个独立项目专门用于依赖重命名。

    5、其他功能

    除了包重命名外,maven-shade-plugin 还支持打入和排除指定的 JAR 包及资源文件。例如:

    <filters>
        <filter>
            <artifact>*:*artifact>
            <excludes>
                <exclude>META-INF/*.SFexclude>
                <exclude>META-INF/*.DSAexclude>
                <exclude>META-INF/*.RSAexclude>
            excludes>
        filter>
    filters>
    

    通过这种方式,可以进一步控制打包过程中的细节,满足不同的需求。

  • 相关阅读:
    计算机网络-网络层
    SpringBoot利用证书实现https双向绑定并解析客户端证书
    2022 极术通讯-基于安谋科技 “星辰” STAR-MC1的灵动MM32F2570开发板深度评测
    Mybatis-plus如何快速实现动态数据源切换?
    图像的高频和低频细节
    【JavaWeb】JavaScript
    【Linux】部署单体项目以及前后端分离项目(项目部署)
    Hive-SQL
    【elasticsearch实战】从零开始设计全站搜索引擎
    uniapp部分知识总结
  • 原文地址:https://blog.csdn.net/weixin_45187434/article/details/139485060