美文网首页
依赖版本引用全对比

依赖版本引用全对比

作者: 喏喏2021 | 来源:发表于2021-12-30 16:28 被阅读0次

1. 背景

当我们使用maven管理jar包依赖时,经常会发生jar包冲突的情况,大多数时候,可能就是排除一下冲突包就可以,但可能呢,你发现就只修改了一个jar包的依赖,项目启动时,就会报各种各样的异常,比如某个类,或是方法找不到。
造成上面的情况,主要原因是修改某一个依赖后,最终有效的jar包列表发生了变化,我们需要能有一个好的办法,可以快速知道修改前后的jar包变化呢,这样对于我们排除就会比较方便一点,下面的处理可能会对你有帮助。

2. 处理后的对比输出

我们先来看一下,我们经过处理后,得到的对比结果


不同版本依赖差异.png

从上面的输出(用printf格式化输出,看得方便一点)我们可以清晰看出:

  1. 一共有多少个差异,比如上面共有9个差异
  2. 列表中可以看出groupId,artifactId
  3. 最后是版本号对比,可能其中一个版本缺少了某个jar,可以清晰地看出来

3. 实现步骤

  • 第一步 生成第1个依赖树文件

    在命令行,进入项目的目录,用命令生成依赖树文件
mvn dependency:tree > project_dependency_1.0.1.txt

这样我们就会在项目目录下,生成1.0.1版本的依赖树文件

  • 第二步 生成第2个依赖树文件

    回到项目中,修改相应的依赖版本,再回到目录,生成第2个依赖树文件
mvn dependency:tree > project_dependency_1.0.2.txt

这时,就会在我们的项目目录下,生成两个依赖树文件

project_dependency_1.0.1.txt
project_dependency_1.0.2.txt
  • 第三步 解析这两个文件,输出对比

我们先看依赖树文件,我们关注的是下面一段

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ project_name ---
[INFO] +- com.github.knightliao.apollo:apollo:jar:1.0.14:compile
[INFO] |  +- commons-lang:commons-lang:jar:2.4:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-core:jar:2.6.0:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.6.0:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.0:compile
[INFO] |  +- com.google.code.gson:gson:jar:2.3:compile
[INFO] |  +- javax.servlet:servlet-api:jar:2.4:compile
[INFO] |  \- redis.clients:jedis:jar:2.1.0:compile

我们主要关注这3个点:

  1. 真实解析出来的依赖树的开始输出位置,就是下面这个标识开始
    maven-dependency-plugin
  2. 提取特征呢,我们以某一行是包含jar字符串
  3. 解析出groupId,artifactId,version
    比如从这一行,我们可以解析出来
[INFO] |  \- redis.clients:jedis:jar:2.1.0:compile

groupId : 第一个冒号前
artifactId : 第一个冒号与第2个冒号之间
version: 第2个冒号到":compile"串前
下面是实现代码

public class MavenDepenTreeCompare {
    public static void main(String[] args) throws IOException {
        //依赖树文件
        String parentPath = "这里请替换成你输出文件的目录";
        String name1 = "project_dependency_1.0.1.txt";
        String name2 = "project_dependency_1.0.2.txt";
        
        //从两个文件中,读取出依赖版本信息
        List<JarInfo> v1List = getJarInfoList(parentPath+name1);
        List<JarInfo> v2List = getJarInfoList(parentPath+name2);
        Set<JarInfo> vAllSet = new LinkedHashSet<JarInfo>();
        
        vAllSet.addAll(v1List);
        vAllSet.addAll(v2List);
        
                //版本比较并输出
        compareVersion(v1List,v2List,vAllSet);
        
    }
    
    //从文件获得jarInfo列表
    public static List<JarInfo> getJarInfoList(String filePath) throws IOException{
        List<JarInfo> resultList = new ArrayList<JarInfo>();
        List<String> fileList = FileUtils.readLines(new File(filePath));
        boolean rowBegin = false;
        String beginFlag = "maven-dependency-plugin";
        for(String row : fileList) {
            if(!rowBegin && row.indexOf(beginFlag)>=0) {
                rowBegin = true;
            }
            if(!rowBegin) {
                continue;
            }
            
            JarInfo jarInfo = getJarVersion(row);
            if(null==jarInfo) {
                continue;
            }
            
            resultList.add(jarInfo);
        }
        return resultList;
    }
    
    //从list查找,找到则返回,找不到则返回null
    public static JarInfo findJar(JarInfo info,List<JarInfo> infoList) {
        JarInfo result = null;
        int findIndex = infoList.indexOf(info);
        if(findIndex<0) {
            return result;
        }else {
            return infoList.get(findIndex);
        }
    }
    
        //比较两个列表,并进行格式化输出
    public static void compareVersion(List<JarInfo> v1List,List<JarInfo> v2List,Set<JarInfo> vAllSet) {
        int index = 0;
        for(JarInfo jarInfo : vAllSet) {
            JarInfo v1Info = findJar(jarInfo,v1List);
            JarInfo v2Info = findJar(jarInfo,v2List);
            if(v1Info==null || v2Info==null) {
                System.out.printf("%-3s %-50s【%s ~ %s】\r\n",
                        ++index , jarInfo.getArtifactInfo(),v1Info==null?"":v1Info.version,v2Info==null?"":v2Info.version);
                continue;
            }
            if(!v1Info.version.equals(v2Info.version)) {
                System.out.printf("%-3s %-50s【%s ~ %s】\r\n",
                        ++index , jarInfo.getArtifactInfo(),v1Info.version,v2Info.version);
            }
        }
    }
    
        //根据字符串行,生成依赖信息
    public static JarInfo getJarVersion(String row) {
        if(row.indexOf("jar")>=0) {
            row = row.replace(":jar", "");
            String jarInfoStr = row.substring(row.lastIndexOf(" ")+1, row.indexOf(":compile"));
            int firstIndex = jarInfoStr.indexOf(":"); 
            int secondIndex = jarInfoStr.lastIndexOf(":");
            return new JarInfo(jarInfoStr.substring(0,firstIndex),jarInfoStr.substring(firstIndex+1,secondIndex),jarInfoStr.substring(secondIndex+1));
        }else {
            return null;
        }
    }
    
        //用来存放groupId,artifactId,version信息
    static class JarInfo {
        public String groupId;
        public String artifactId;
        private String version;
        public JarInfo(String groupId,String artifactId,String version) {
            this.groupId = groupId;
            this.artifactId = artifactId;
            this.version = version;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((artifactId == null) ? 0 : artifactId.hashCode());
            result = prime * result + ((groupId == null) ? 0 : groupId.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            JarInfo other = (JarInfo) obj;
            if (artifactId == null) {
                if (other.artifactId != null)
                    return false;
            } else if (!artifactId.equals(other.artifactId))
                return false;
            if (groupId == null) {
                if (other.groupId != null)
                    return false;
            } else if (!groupId.equals(other.groupId))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return groupId + "." + artifactId + "." + version;
        }
        
        public String getArtifactInfo() {
            return groupId + "." + artifactId;
        }
    }
}   

最终的输出结果呢,就是上面贴出来的。
是否对您有帮助呢,可以点个赞哦!

相关文章

网友评论

      本文标题:依赖版本引用全对比

      本文链接:https://www.haomeiwen.com/subject/oyngqrtx.html