为 Oozie Java 操作的类路径中的所有 jar 捕获组、工件和版本

capture group, artifact, and version for all the jars in the classpath for an Oozie Java action

我最近被要求解决由 Oozie 执行的 Spring 引导程序的问题。不幸的是,我无权访问 Spring 启动应用程序或日志。 :) 我 domvn dependency:tree -Ddetail=true

的输出

我听说 Spring 引导应用程序 运行 本身很好,但当作为 Oozie Java 操作执行时 运行 就不行了。我们怀疑 Oozie 添加到 classpath 的某些依赖项与来自 Spring Boot.

的依赖项冲突

这有点推测性,但我想 运行 一个简单的 Oozie Java 操作来捕获添加到 classpath 并将其与 Spring Boot 应用程序的依赖树进行比较。我在想,如果有版本冲突,可能 exclude/resolve 它们在 pom.xml.

我写了一个 class 将 class 路径中的罐子名称写入文本文件:

void captureClasspath(){

    PrintWriter out = null;
    try {
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        URL[] urls = ((URLClassLoader)cl).getURLs();

        out = new PrintWriter(new OutputStreamWriter(
                new BufferedOutputStream(new FileOutputStream("/tmp/classpath_capture.txt")), "UTF-8"));

        for (URL url : urls){
            out.println(url.getFile());
        }

    } catch (UnsupportedEncodingException | FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if(out != null) {
            out.flush();
            out.close();
        }
    }

}

输出如下所示:

/hadoop/yarn/local/filecache/10/mapreduce.tar.gz/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.1.2.4.3.0-227-tests.jar
/hadoop/yarn/local/filecache/10/mapreduce.tar.gz/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.1.2.4.3.0-227.jar
/hadoop/yarn/local/filecache/10/mapreduce.tar.gz/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.7.1.2.4.3.0-227.jar
/hadoop/yarn/local/filecache/10/mapreduce.tar.gz/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-hs-2.7.1.2.4.3.0-227.jar
/hadoop/yarn/local/filecache/10/mapreduce.tar.gz/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.1.2.4.3.0-227.jar
... etc ... (more than 300 lines)

我想从这些 jar 中提取组、工件和版本,而不是文件名。那可能吗?或者在输入有限(没有应用程序日志、代码等...)的情况下,troubleshoot/resolve 这个问题是否有更好的策略?

Instead of the filename, I'd like to extract the group, artifact and version from these jars. Is that possible?

这需要读取每个 jar 文件的内容并从 jar 文件中的相关条目中提取组、工件和版本。一些相关的实现方法是 JarFile#entries(), JarFile#getEntry(String) and JarFile#getInputStream(ZipEntry).

Maven 构建将在 META-INF/maven/<group>/<artifact>/pom.properties 的 jar 中存储一个条目。例如,运行 jar xf hadoop-common.jar 提取 META-INF/maven/org.apache.hadoop/hadoop-common/pom.properties,其中包含以下数据:

#Generated by Maven
#Thu Aug 18 01:41:25 UTC 2016
version=2.7.3
groupId=org.apache.hadoop
artifactId=hadoop-common

Hadoop 应用程序类路径版本冲突的几个常见来源是 Guava、Jackson 和 Protobuf。