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.xml
和 pom.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")));
}
我想从 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.xml
和 pom.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")));
}