【问题标题】:How to get Jar dependencies list如何获取 Jar 依赖项列表
【发布时间】:2017-12-27 07:46:57
【问题描述】:

我想列出通过 maven 项目构建创建的 jar 文件的所有依赖项。我怎样才能在java中实现这一点?我通过 maven 命令mvn:dependency 知道它,但我想以编程方式完成它。 有什么帮助吗?

【问题讨论】:

  • mvn dependency:tree?以编程方式是什么意思?目的是什么?
  • 我的意思是在 java 中 .. 如果给出了 jar 文件路径,我可以知道它的依赖 jars(第 3 方 jars)吗?
  • jar 文件并没有真正的帮助...因为您需要一个 pom 文件(通常,如果您使用 Maven 构建 jar,则 pom 文件通常包含在 jar 中,但不一定)。到目前为止,您已经回答使用 Java ..但是这样做的目的是什么?你想解决什么样的问题?

标签: java maven maven-plugin


【解决方案1】:

一般来说,这很困难。你可以做什么:

  1. 抓取jar的pom.xml,放入一个空目录,通过ProcessBuilder调用“mvn dependency:list”。解析结果,您将获得依赖项列表。但是,如果 pom.xml 不能被解释为独立项目的 pom(例如,如果它是多模块构建的一部分),这可能会失败。

  2. 尝试使用 Aether 来确定依赖项列表,而不是使用 ProcessBuilder。潜在问题同上。

【讨论】:

【解决方案2】:

下面的暴力破解方法可以成功获取依赖(3rd party)jars的所有绝对路径。用您自己的方法替换“FileUtils.getFileListRecursively”和“FileUtils.readLines”。

FileUtils.getFileListRecursively("src")

从当前java项目的'src'文件夹中读取绝对文件路径,并且

FileUtils.readLines(filePath)

将文件作为文本文件读取,并将所有行作为字符串的 ArrayList 返回。

    HashSet<String> jarLocationsSet = new HashSet<>();

    final String importString = "import ";
    final String javaString = "java";
    ArrayList<String> fileList = FileUtils.getFileListRecursively("src");
    for (String filePath : fileList) {
        if (filePath.endsWith(javaString) == false){
            continue;
        }
        List<String> lines = FileUtils.readLines(filePath);

        for (String line : lines) {

            int isecl = line.indexOf(';');
            if (line.contains(importString) == false || isecl < 0){
                continue;
            }
            if (line.contains("static")){
                continue;
            }
            int start = line.indexOf(importString);
            line = line.substring(start + importString.length(), isecl);
            if (line.startsWith(javaString)){
                continue;
            }
            Class<?> clazz = null;
            try {
                clazz = Class.forName(line, false, ClassLoader.getSystemClassLoader());
            } catch (Exception e) {
            }
            if (clazz == null){
                continue;
            }


            URL location = clazz.getResource('/'+clazz.getName().replace('.', '/') + ".class");
            String locationString = location.toString();
            int jarIndex= locationString.indexOf(".jar");
            if (jarIndex < 0){
                continue;
            }
            locationString = locationString.substring(0, jarIndex + 4);
            jarLocationsSet.add(locationString);
        }

    }


    for (String jarLocation : jarLocationsSet) {
        System.out.println("jarLocation = " + jarLocation);
    }

【讨论】:

  • 编辑:该方法可以获取本java项目中至少一次使用的所有jar文件(jar文件中的任何一个类都被使用)。
【解决方案3】:

阅读 pom 文件并找出其中的内容是个坏主意,因为一个依赖项可以被其他依赖项多次导入不同版本号的依赖项,并且它可以变得非常深,maven 有自己的方式来决定要哪个版本采用。大致思路是读取最终的jar文件,找到里面所有jar的文件夹。

RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean();
String classPath = bean.getClassPath();//    /opt/spring-boot/app.jar
ZipFile jarFile = new ZipFile(classPath);
Enumeration<? extends ZipEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
                ZipEntry zipEntry = entries.nextElement();
                if (!zipEntry.isDirectory()) {
                 system.out.println( zipEntry.getName());  
                }
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 2013-09-05
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多