依賴版本引用全對(duì)比

1. 背景

當(dāng)我們使用maven管理jar包依賴時(shí)悬槽,經(jīng)常會(huì)發(fā)生jar包沖突的情況,大多數(shù)時(shí)候影斑,可能就是排除一下沖突包就可以给赞,但可能呢,你發(fā)現(xiàn)就只修改了一個(gè)jar包的依賴矫户,項(xiàng)目啟動(dòng)時(shí)片迅,就會(huì)報(bào)各種各樣的異常,比如某個(gè)類皆辽,或是方法找不到障涯。
造成上面的情況罐旗,主要原因是修改某一個(gè)依賴后,最終有效的jar包列表發(fā)生了變化唯蝶,我們需要能有一個(gè)好的辦法九秀,可以快速知道修改前后的jar包變化呢,這樣對(duì)于我們排除就會(huì)比較方便一點(diǎn)粘我,下面的處理可能會(huì)對(duì)你有幫助鼓蜒。

2. 處理后的對(duì)比輸出

我們先來看一下,我們經(jīng)過處理后征字,得到的對(duì)比結(jié)果


不同版本依賴差異.png

從上面的輸出(用printf格式化輸出都弹,看得方便一點(diǎn))我們可以清晰看出:

  1. 一共有多少個(gè)差異,比如上面共有9個(gè)差異
  2. 列表中可以看出groupId匙姜,artifactId
  3. 最后是版本號(hào)對(duì)比畅厢,可能其中一個(gè)版本缺少了某個(gè)jar,可以清晰地看出來

3. 實(shí)現(xiàn)步驟

  • 第一步 生成第1個(gè)依賴樹文件

    在命令行氮昧,進(jìn)入項(xiàng)目的目錄框杜,用命令生成依賴樹文件
mvn dependency:tree > project_dependency_1.0.1.txt

這樣我們就會(huì)在項(xiàng)目目錄下,生成1.0.1版本的依賴樹文件

  • 第二步 生成第2個(gè)依賴樹文件

    回到項(xiàng)目中袖肥,修改相應(yīng)的依賴版本咪辱,再回到目錄,生成第2個(gè)依賴樹文件
mvn dependency:tree > project_dependency_1.0.2.txt

這時(shí)椎组,就會(huì)在我們的項(xiàng)目目錄下油狂,生成兩個(gè)依賴樹文件

project_dependency_1.0.1.txt
project_dependency_1.0.2.txt
  • 第三步 解析這兩個(gè)文件,輸出對(duì)比

我們先看依賴樹文件寸癌,我們關(guān)注的是下面一段

[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

我們主要關(guān)注這3個(gè)點(diǎn):

  1. 真實(shí)解析出來的依賴樹的開始輸出位置专筷,就是下面這個(gè)標(biāo)識(shí)開始
    maven-dependency-plugin
  2. 提取特征呢,我們以某一行是包含jar字符串
  3. 解析出groupId,artifactId,version
    比如從這一行蒸苇,我們可以解析出來
[INFO] |  \- redis.clients:jedis:jar:2.1.0:compile

groupId : 第一個(gè)冒號(hào)前
artifactId : 第一個(gè)冒號(hào)與第2個(gè)冒號(hào)之間
version: 第2個(gè)冒號(hào)到":compile"串前
下面是實(shí)現(xiàn)代碼

public class MavenDepenTreeCompare {
    public static void main(String[] args) throws IOException {
        //依賴樹文件
        String parentPath = "這里請(qǐng)?zhí)鎿Q成你輸出文件的目錄";
        String name1 = "project_dependency_1.0.1.txt";
        String name2 = "project_dependency_1.0.2.txt";
        
        //從兩個(gè)文件中磷蛹,讀取出依賴版本信息
        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);
        }
    }
    
        //比較兩個(gè)列表,并進(jìn)行格式化輸出
    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);
            }
        }
    }
    
        //根據(jù)字符串行鸟辅,生成依賴信息
    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;
        }
    }
}   

最終的輸出結(jié)果呢氛什,就是上面貼出來的。
是否對(duì)您有幫助呢匪凉,可以點(diǎn)個(gè)贊哦枪眉!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末接癌,一起剝皮案震驚了整個(gè)濱河市政模,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖往枣,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異辩昆,居然都是意外死亡盲再,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門棍鳖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炮叶,“玉大人,你說我怎么就攤上這事渡处【迪ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵医瘫,是天一觀的道長(zhǎng)侣肄。 經(jīng)常有香客問我,道長(zhǎng)醇份,這世上最難降的妖魔是什么稼锅? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮被芳,結(jié)果婚禮上缰贝,老公的妹妹穿的比我還像新娘。我一直安慰自己畔濒,他們只是感情好剩晴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侵状,像睡著了一般赞弥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趣兄,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天绽左,我揣著相機(jī)與錄音,去河邊找鬼艇潭。 笑死拼窥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蹋凝。 我是一名探鬼主播鲁纠,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鳍寂!你這毒婦竟也來了改含?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤迄汛,失蹤者是張志新(化名)和其女友劉穎捍壤,沒想到半個(gè)月后骤视,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹃觉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年专酗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帜慢。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笼裳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粱玲,到底是詐尸還是另有隱情躬柬,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布抽减,位于F島的核電站允青,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卵沉。R本人自食惡果不足惜颠锉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望史汗。 院中可真熱鬧琼掠,春花似錦、人聲如沸停撞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戈毒。三九已至艰猬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埋市,已是汗流浹背冠桃。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留道宅,地道東北人食听。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像污茵,于是被迫代替她去往敵國(guó)和親樱报。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理省咨,服務(wù)發(fā)現(xiàn)肃弟,斷路器玷室,智...
    卡卡羅2017閱讀 134,672評(píng)論 18 139
  • POM 代表“Project Object Model”零蓉。它是 Maven 項(xiàng)目的 XML 表示形式笤受,保存在名為 ...
    rosy_dawn閱讀 1,890評(píng)論 0 1
  • 經(jīng)過Maven生命周期的學(xué)習(xí),我們知道在Maven core中僅僅定義了抽象的生命周期敌蜂,具體的實(shí)現(xiàn)是由插件完成的箩兽,...
    SonyaBaby閱讀 1,276評(píng)論 0 3
  • 一. 什么是maven 基于java的一款跨平臺(tái)的項(xiàng)目構(gòu)建、依賴管理章喉、項(xiàng)目信息管理的工具汗贫。 二.maven安裝和配...
    蒲公英_20cc閱讀 625評(píng)論 0 1
  • 摘要: Maven,坐標(biāo)秸脱,依賴落包,依賴傳遞,依賴范圍Maven的一大功能是管理項(xiàng)目依賴摊唇,為了能自動(dòng)化解析任何一個(gè)ja...
    xiaogp閱讀 562評(píng)論 0 1