在pom文件中,依賴的jar文件非常多,如果有人改了倉庫,例如上傳jar文件中斷導致字節丟失,刪jar、更改版本等,會導致項目無法正常啟動,
雖然我們沒有改動pom文件,但是由於他人的行為,我們很難排查出來是哪個jar出了問題,那么,我們可以將新打包和舊的jar文件進行解壓,提取里面的
lib目錄,進行jar比對,包括名稱、版本、大小及修改時間。
在網上搜索了一陣發現沒有現成好用的工具,於是寫了這個軟件工具。方便排查。
入參:兩個lib目錄
例如:C:\\Users\\o\\Desktop\\lib0", "C:\\Users\\o\\Desktop\\lib2
輸出為比對結果log文件。comprare.log
核心代碼如下:

1 import java.io.File; 2 import java.io.IOException; 3 import java.nio.file.Files; 4 import java.nio.file.Paths; 5 import java.nio.file.StandardOpenOption; 6 import java.text.SimpleDateFormat; 7 import java.util.ArrayList; 8 import java.util.Arrays; 9 import java.util.Date; 10 import java.util.HashMap; 11 import java.util.List; 12 import java.util.Map; 13 import java.util.TreeMap; 14 15 public class MyTest022 { 16 17 public File[] getFileList(String dirPath) { 18 File dirFile = new File(dirPath); 19 if (!dirFile.exists() || !dirFile.isDirectory() || !dirFile.canRead()) { 20 throw new RuntimeException("file(" + dirPath + ")can not exist、un-directory or unread."); 21 } 22 return dirFile.listFiles(); 23 } 24 25 private void parse(File[] files, Map<String, SimpleFile> map, List<File> errorList) { 26 for (int i = 0; i < files.length; i++) { 27 if (isJarFile(files[i])) { 28 SimpleFile sf = new SimpleFile(files[i]); 29 map.put(sf.name, sf); 30 } else { 31 errorList.add(files[i]); 32 } 33 } 34 } 35 36 public StringBuilder compare(String dir1, String dir2) { 37 Map<String, SimpleFile> map1 = new HashMap<>(); //all jar 38 List<File> list1_error = new ArrayList<>(); //log 39 parse(getFileList(dir1), map1, list1_error); 40 41 Map<String, SimpleFile> map2 = new HashMap<>(); //all jar 42 List<File> list2_error = new ArrayList<>(); //log 43 parse(getFileList(dir2), map2, list2_error); 44 45 Map<String, List<SimpleFile>> result = new TreeMap<>((o1, o2) -> o1.compareTo(o2)); 46 for (String name1 : map1.keySet()) { 47 SimpleFile sf = map1.get(name1); 48 if (map2.keySet().contains(name1)) { 49 if (!map2.values().contains(sf)) { 50 result.put("1_"+name1, Arrays.asList(sf, map2.get(name1))); 51 } else { 52 result.put("0_"+name1, Arrays.asList(sf, sf)); 53 } 54 } else { 55 result.put("2_"+name1, Arrays.asList(sf, null)); 56 } 57 } 58 59 for (String name2 : map2.keySet()) { 60 if (!map1.keySet().contains(name2)){ 61 result.put("2_"+name2, Arrays.asList(null, map2.get(name2))); 62 } 63 } 64 65 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 66 StringBuilder stringBuilder = new StringBuilder("|序號|--——---|名 稱|-------------------------|比對結果|---------|源目錄文件信息[版本、大小、更新時間]|-----------------------|目標文件信息[版本、大小、更新時間]|-----------\n"); 67 68 int count = 0; 69 for (String name : result.keySet()) { 70 List<SimpleFile> list = result.get(name); 71 SimpleFile sf = list.get(0); 72 String ne = name.substring(2); 73 count++; 74 if (name.startsWith("0_")) { 75 stringBuilder.append(format(" "+count, 10) + format(ne, 38) + format("[正常]", 18) + format(sf.version, 18) + format(sf.size+"B", 13) + format(sdf.format(new Date(sf.update)), 27)); 76 } else if (name.startsWith("1_")) { 77 SimpleFile sf2 = list.get(1); 78 stringBuilder.append(format(" "+count, 10) + format(ne, 38) + format("[不相同]", 17) + format(sf.version, 18) + format(sf.size+"B", 13) + format(sdf.format(new Date(sf.update)), 30) 79 + format(sf2.version, 18) + format(sf2.size+"B", 13) + format(sdf.format(new Date(sf2.update)), 27)); 80 } else if (name.startsWith("2_")){ 81 if (sf == null) { 82 SimpleFile sf2 = list.get(1); 83 stringBuilder.append(format(" "+count, 10) + format(ne, 38) + format("[不存在]", 17) + format("不存在", 58) + format(sf2.version, 18) + format(+sf2.size+"B", 13) + format(sdf.format(new Date(sf2.update)), 27)); 84 } else { 85 stringBuilder.append(format(" "+count, 10) + format(ne, 38) + format("[不存在]", 17) + format(sf.version, 18) + format(sf.size+"B", 13) + format(sdf.format(new Date(sf.update)), 27) + format("不存在", 30)); 86 } 87 } else { 88 stringBuilder.append(format(" "+count, 10) + format(ne, 38)+"[ERROR]這是什么玩意>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); 89 } 90 stringBuilder.append("\n"); 91 } 92 return stringBuilder; 93 } 94 95 private String format(String s, int len) { 96 if (s == null) s = ""; 97 if (s.length() >= len) { 98 return s; 99 } 100 return format(s+" ", len); 101 } 102 103 public static void main(String[] args) throws IOException { 104 MyTest022 test022 = new MyTest022(); 105 StringBuilder log = test022.compare("C:\\Users\\o\\Desktop\\lib1", "C:\\Users\\o\\Desktop\\lib2"); 106 Files.write(Paths.get("C:\\Users\\o\\Desktop\\comprare.log"),log.toString().getBytes(), StandardOpenOption.TRUNCATE_EXISTING); 107 } 108 109 public static boolean isJarFile(File file) { 110 if (file.exists() && file.isFile() && file.getName().length() > 7) { 111 return file.getName().toLowerCase().endsWith(".jar") 112 && file.getName().indexOf("-") > 0; 113 } 114 return false; 115 } 116 117 class SimpleFile { 118 String name; 119 String version; 120 long size; 121 long update; 122 public SimpleFile(File file) { 123 int index = file.getName().lastIndexOf("-"); 124 this.name = file.getName().substring(0, index); 125 this.version = file.getName().substring(index+1, file.getName().length()-4); 126 this.size = file.length(); 127 this.update = file.lastModified(); 128 } 129 public int hashCode(){ 130 return this.toString().hashCode(); 131 } 132 @Override 133 public boolean equals(Object o) { 134 return this.toString().equals(o.toString()); 135 } 136 public String toString() { 137 return new StringBuilder(name).append(version).append(size).append(update).toString(); 138 } 139 } 140 }
可視化界面如下:
備注:可視化工具及源碼如有需要,因為此為作者原創,版權原因(需要付費1元,備注Maven可視化工具,即可發至郵箱),如有需要可留言聯系作者,請尊重作者時間和精力的耗費,見諒!