简体   繁体   中英

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

I want to access some information from the pom.xml to display in a Info dialog. So I googled and found 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());
    }
}

I implemented it in my tool, added

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

to my pom and was happy that everything ran as expected when I run the tool from the project root directory with java -jar target\\mytool.jar .

When I move to any other directory, eg directly into target and execute my tool with java -jar mytool.jar , I get:

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)

Which is kind of comprehensible. How should the code know, where the pom.xml is located, as it is not a resource. Is there any way to work around that?

In the mean time I use the approach from this thread to obtain the version and artifactID.

The problem is that

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

tries to read the POM from the directory where your program is executed. Normally, pom.xml won't get copied to target , but it is embedded in the resulting artifact. You can override and force Maven to copy the POM to the target directory if you want to (for your own project), but it won't help you for other Maven artifacts.

Most of the time, a Maven artifact will have the POM coordinates included in the JAR/WAR/EAR output. If you unpack such a file, you'll notice that there are two files stored under META-INF/maven/<groupId>/<artifactId> : pom.xml and pom.properties where the latter is far easier to parse than pom.xml but it doesn't include the dependencies.

Parsing the embedded pom.xml from the classpath (and not from disk) should work better for you, especially if you always run your program with java -jar target\\mytool.jar . In your program, try this:

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> and <your artifactId> should be fairly static, but if you do relocate your artifact's coordinates, then you need to change this in your code as well.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM