【问题标题】:Maven: Access POM at runtime - How to get 'pom.xml' available from anywhere?Maven:在运行时访问 POM - 如何从任何地方获取“pom.xml”?
【发布时间】:2019-10-22 06:39:37
【问题描述】:

我想从pom.xml 访问一些信息以显示在信息对话框中。于是我google了一下,发现this post

public class MavenModelExample {
    public static void main(String[] args) throws IOException, XmlPullParserException {
        MavenXpp3Reader reader = new MavenXpp3Reader();
        Model model = reader.read(new FileReader("pom.xml"));
        System.out.println(model.getId());
        System.out.println(model.getGroupId());
        System.out.println(model.getArtifactId());
        System.out.println(model.getVersion());
    }
}

我在我的工具中实现了它,添加

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-model</artifactId>
  <version>3.3.9</version>
</dependency>

致我的 pom,很高兴当我使用 java -jar target\mytool.jar 从项目根目录运行该工具时,一切都按预期运行。

当我移动到任何其他目录时,例如直接进入target 并使用java -jar mytool.jar 执行我的工具,我得到:

java.io.FileNotFoundException: pom.xml (The system cannot find the specified file)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:110)
        at java.base/java.io.FileReader.<init>(FileReader.java:60)

这是可以理解的。代码应该如何知道pom.xml 的位置,因为它不是资源。有没有办法解决这个问题?

同时我使用this thread的方法来获取版本和artifactID。

【问题讨论】:

  • 贴出代码,以便 SO 成员可以帮助您。
  • 我会尝试资源过滤而不是读取 POM。您需要哪些信息?
  • 目前我主要想检索我的工具的artifactID和版本。但后来我也想访问依赖版本

标签: java maven runtime pom.xml


【解决方案1】:

问题是

Model model = reader.read(new FileReader("pom.xml"));

尝试从执行程序的目录中读取 POM。通常,pom.xml 不会被复制到 target,但它会嵌入到生成的工件中。如果您愿意(对于您自己的项目),您可以覆盖并强制 Maven 将 POM 复制到 target 目录,但它对其他 Maven 工件没有帮助。

大多数时候,Maven 工件的 POM 坐标会包含在 JAR/WAR/EAR 输出中。如果您解压缩这样的文件,您会注意到META-INF/maven/&lt;groupId&gt;/&lt;artifactId&gt; 下存储了两个文件:pom.xmlpom.properties,后者比pom.xml 更容易解析,但它不包含依赖项。

从类路径(而不是从磁盘)解析嵌入的pom.xml 应该对您更有效,特别是如果您总是使用java -jar target\mytool.jar 运行程序。在你的程序中,试试这个:

try (InputStream is = MavenModelExample.class.getClassLoader().getResourceAsStream("META-INF/maven/<your groupId>/<your artifactId>/pom.xml")) {
            MavenXpp3Reader reader = new MavenXpp3Reader();
            Model model = reader.read(is);
            System.out.println(model.getId());
            System.out.println(model.getGroupId());
            System.out.println(model.getArtifactId());
            System.out.println(model.getVersion());

            // If you want to get fancy:
            model.getDependencies().stream().forEach(System.out::println);  

        }
        catch (IOException e) {
            // Do whatever you need to do if the operation fails.
        }

&lt;your groupId&gt;&lt;your artifactId&gt; 应该是相当静态的,但是如果您确实重新定位了工件的坐标,那么您也需要在代码中进行更改。

【讨论】:

    【解决方案2】:

    问题是:

    read(new FileReader("pom.xml")) 
    

    当您从 STS 或其他方式启动应用程序时工作正常,但是当您将应用程序构建为 JAR 时,pom.xml 文件的路径更改为:

    META-INF/maven/${groupId}/${artifactId}/pom.xml

    为此,请尝试以下代码:

    MavenXpp3Reader mavenXpp3Reader = new MavenXpp3Reader();
    Model model;
    if ((new File("pom.xml")).exists()) {
      model = mavenXpp3Reader.read(new FileReader("pom.xml"));
    }
    else {
     // Packaged artifacts contain a META- INF/maven/${groupId}/${artifactId}/pom.properties
      model = mavenXpp3Reader.read(new 
      InputStreamReader(Application.class.getResourceAsStream(
        "/META-INF/maven/groupId/artifactId/pom.xml")));
    }
    

    【讨论】:

    • 感谢您的回答;你能edit你的答案添加一个简短的总结,说明这如何帮助解决原始问题。
    猜你喜欢
    • 2011-02-18
    • 2012-12-21
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 2021-12-15
    • 2020-03-21
    相关资源
    最近更新 更多