Maven:在运行时访问 POM - 如何从任何地方获取 'pom.xml'?

Maven: Access POM at runtime - How to get 'pom.xml' available from anywhere?

我想从 pom.xml 访问一些信息以显示在信息对话框中。所以我用谷歌搜索并找到 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。

问题在于

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

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

大多数时候,Maven 工件的 JAR/WAR/EAR 输出中包含 POM 坐标。如果你解压这样一个文件,你会注意到 META-INF/maven/<groupId>/<artifactId> 下存储了两个文件: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.
        }

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

问题在于:

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")));
}