1. 背景
当我们使用maven管理jar包依赖时,经常会发生jar包冲突的情况,大多数时候,可能就是排除一下冲突包就可以,但可能呢,你发现就只修改了一个jar包的依赖,项目启动时,就会报各种各样的异常,比如某个类,或是方法找不到。
造成上面的情况,主要原因是修改某一个依赖后,最终有效的jar包列表发生了变化,我们需要能有一个好的办法,可以快速知道修改前后的jar包变化呢,这样对于我们排除就会比较方便一点,下面的处理可能会对你有帮助。
2. 处理后的对比输出
我们先来看一下,我们经过处理后,得到的对比结果
不同版本依赖差异.png
从上面的输出(用printf格式化输出,看得方便一点)我们可以清晰看出:
- 一共有多少个差异,比如上面共有9个差异
- 列表中可以看出groupId,artifactId
- 最后是版本号对比,可能其中一个版本缺少了某个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个点:
- 真实解析出来的依赖树的开始输出位置,就是下面这个标识开始
maven-dependency-plugin - 提取特征呢,我们以某一行是包含jar字符串
- 解析出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;
}
}
}
最终的输出结果呢,就是上面贴出来的。
是否对您有帮助呢,可以点个赞哦!
网友评论