从公司gitlab获取所有java项目依赖的jar包坐标
背景
公司“安全专员”想方便的拿到公司所有java项目依赖的jar包坐标,方便他从“论坛”上发现什么jar存在安全漏洞时,及时知道我们公司是否也有对该jar包的依赖,以及对应的项目和负责人。
分析
我们内部代码管理工具是gitlab,采用master
分支发布,只需分析master
依赖即可。
思路是先拿到所有项目的代码,然后通过maven dependency插件获取到依赖的jar包坐标,然后分析出其中jar包坐标整理到文档中。最好也拿到项目的负责人信息。
初步想到步骤:
- 从内部gitlab机器用盘上拷贝
- 执行
mvn dependency:tree --log-file xxx
- 从产生的日志中分析出依赖的jar坐标
这个想想都觉得慢的受不了,好几个G的小文件,光从用盘上拷贝都要花费不少时间。
另外直接执行maven dependency:tree
也不能成功,因为依赖的本项目中的其他module不存在,需要先打包。
另外拿不到项目负责人信息。
改进版本一:
- 通过gitlab api拿到所有项目信息,包括负责人信息,每个执行
git clone xxx
得到所有代码,再次执行时执行git pull origin master
- 执行
mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true dependency:tree --log-file xxx
- 从产生的日志中分析出依赖的jar坐标
能够拿到应用负责人信息,但仍然慢的让人崩溃。
另外有些项目执行mvn package
因为代码原因会失败,导致mvn dependency:tree
无法继续执行。
改进版本二:
- 通过gitlab api拿到所有项目信息,包括负责人信息, 通过gitlab api下载每个项目
master
分支中的所有pom.xml
。 - 对于根目录存在
pom.xml
的项目执行mvn install -f xxx/xxx/pom.xml
,web
模块通常会失败,不过没关系, 其他模块成功就行。 - 执行
mvn dependency:tree -f xxx/xxx/pom.xml
- 使用apache
commons-exec
执行dependency:tree
命令,同时分析产生的日志。
第二步对只有pom.xml
的项目执行mvn install
,web
模块通常会失败,不过没关系,需要的是其他模块,因为执行mvn dependency:tree
时web
模块需要依赖到其他模块。
一两百个java项目,2核的机器20多分钟跑完,产生结果,基本满意。
也可以继续优化下,借助jprofiler等工具找到耗时点、调整执行线程池大小等。
代码
maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId>
<version>4.4.3</version>
</dependency>
代码片段说明
Pattern pattern = Pattern.compile("(([\\w\\-\\.\\d]+):([\\w\\-\\.