从公司gitlab获取所有依赖的jar包坐标
2017-08-09 13:03
741 查看
从公司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</ 4000 groupId> <artifactId>gitlab4j-api</artifactId> <version>4.4.3</version> </dependency>
代码片段说明
Pattern pattern = Pattern.compile("(([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+))"); String str = "[INFO] +- javax.servlet:servlet-api:jar:2.5:provided\n"; Matcher matcher = pattern.matcher(str); if (matcher.find()) { System.out.println(matcher.group()); System.out.println(matcher.group(1)); System.out.println(matcher.group(2)); System.out.println(matcher.group(3)); System.out.println(matcher.group(4)); System.out.println(matcher.group(5)); System.out.println(matcher.group(6)); }
通过上述正则表达式,找出jar包坐标,输出结果为:
javax.servlet:servlet-api:jar:2.5:provided javax.servlet:servlet-api:jar:2.5:provided javax.servlet servlet-api jar 2.5 provided
完整代码
static String baseDir = "/Users/xxx/tmp/gitlab/"; static String targetFile = "/Users/xxx/tmp/dependency.csv"; static BufferedWriter store; static { try { store = new BufferedWriter(new FileWriter(new File(targetFile))); } catch (IOException e) { throw new RuntimeException(e); } } static GitLabApi api = new GitLabApi("http://xxxxxx", "xxxxxxx"); static Pattern pattern = Pattern.compile("(([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+):([\\w\\-\\.\\d]+))"); static Executor executor = Executors.newFixedThreadPool(5, new ThreadFactory() { private final AtomicInteger threadNum = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { String name = "collector-" + threadNum.getAndIncrement(); Thread ret = new Thread(r, name); ret.setDaemon(true); return ret; } }); public static void main(String[] args) throws GitLabApiException, IOException, InterruptedException { Map<Group, List<Project>> groupMap = new HashMap<Group, List<Project>>(); int count = 0; for (Group group : api.getGroupApi().getGroups()) { List<Project> projects = api.getGroupApi().getProjects(group.getId()); if (projects != null) { groupMap.put(group, projects); count += projects.size(); } } final CountDownLatch latch = new CountDownLatch(count); for (final Map.Entry<Group, List<Project>> entry : groupMap.entrySet()) { final Group group = entry.getKey(); for (final Project project : entry.getValue()) { executor.execute(new Runnable() { @Override public void run() { try { if (copyPomFileFromGitlab(project.getId(), project.getName(), group.getName())) { executeMavenInstall(group.getName(), project.getName()); executeMavenDependencyTree(project.getCreatorId(), group.getName(), project.getName()); } } catch (Exception e) { e.printStackTrace(); } finally { latch.countDown(); } } }); } } latch.await(); System.out.println("*******************执行结束*********************"); System.out.println("*******************执行结束*********************"); System.out.println("*******************执行结束*********************"); } private static boolean copyPomFileFromGitlab(Integer projectId, String projectName, String groupName) throws GitLabApiException, IOException { boolean rootPomExists = false; Pager<TreeItem> pager = api.getRepositoryApi().getTree(projectId, "/", "master", true, 100); while (pager.hasNext()) { for (TreeItem item : pager.next()) { if (item.getType() == TreeItem.Type.BLOB && item.getName().equals("pom.xml")) { rootPomExists = item.getPath().equals("pom.xml"); File file = new File(baseDir + groupName + "/" + projectName + "/" + item.getPath()); createFile(file, false); copy(api.getRepositoryFileApi().getRawFile(projectId, "master", item.getPath()), new FileOutputStream(file)); } } } return rootPomExists; } private static void executeMavenInstall(String group, String project) { try { DefaultExecutor exec = new DefaultExecutor(); exec.setStreamHandler(new PumpStreamHandler(new LogOutputStream() { @Override protected void processLine(String line, int logLevel) { } })); exec.execute(CommandLine.parse(String.format("mvn install -f %s%s/%s/pom.xml", baseDir, group, project))); } catch (Exception ex) { ex.printStackTrace(); } } private static void executeMavenDependencyTree(Integer creatorId, final String group, final String project) throws GitLabApiException, IOException { final User user = api.getUserApi().getUser(creatorId); LogOutputStream outputStream = new LogOutputStream() { @Override protected void processLine(String s, int i) { if (s.startsWith("[ERROR]")) { System.out.println(s); return; } Matcher matcher = pattern.matcher(s); if (matcher.find()) { System.out.println(matcher.group()); try { store.write( String.format("%s,%s,%s,%s,%s,%s\n", group, project, user.getEmail(), matcher.group(2), matcher.group(3), matcher.group(5))); store.flush(); } catch (IOException e) { e.printStackTrace(); } } } }; DefaultExecutor exec = new DefaultExecutor(); exec.setStreamHandler(new PumpStreamHandler(outputStream, outputStream)); exec.execute(CommandLine.parse(String.format("mvn dependency:tree -f %s%s/%s/pom.xml", baseDir, group, project))); } private static void copy(InputStream inputStream, OutputStream outputStream) throws IOException { byte[] bytes = new byte[1024]; int count; while ((count = inputStream.read(bytes)) > 0) { outputStream.write(bytes, 0, count); } } private static void createFile(File file, boolean directory) throws IOException { if (!file.exists()) { createFile(file.getParentFile(), true); if (directory) { file.mkdir(); } else { file.createNewFile(); } System.out.println("create:" + file.getPath()); } }
相关文章推荐
- 一招教你快速获取Maven Dependencies依赖库里面的所有jar包!!!简单粗暴有效
- 使用Maven开发编译Java项目时如何将所有依赖jar包都打入war包
- Java获取package下所有的class对象(普通文件包和Jar文件包)
- maven 构建可执行 jar ,并引入所需所有依赖 jar
- SuperMap-AjaxMap应用1 使用TCPMap获取图形的所有坐标
- WPF中获取指定坐标依赖对象数据项
- Gradle打jar包,包含所有依赖
- Maven 获取依赖的jar 包
- 详解Android获取所有依赖库的几种方式
- maven连同所有依赖包一起打包成jar包
- Intellij IDEA 中如何查看maven项目中所有jar包的依赖关系图
- 【Maven学习】Maven打包生成包含所有依赖的jar包
- Maven打包,并获取依赖的jar包 ,设置main方法启动
- spring framework体系结构及内部各模块jar之间的maven依赖关系[即spring引入所需要的所有jar包]
- 获取指定包名下继承或者实现某接口的所有类(扫描文件目录和所有jar)
- 获取jar包中某一目录下实现了接口的所有类
- Maven中将所有依赖的jar包全部导出到文件夹
- idea打包java程序(包含依赖的所有jar包)
- 通过pom获取Jar包与有jar包向pom中添加依赖
- Maven打包生成包含所有依赖的jar包