How can I see where portions of an effective pom (in Maven) come from?
Asked Answered
I

2

17

I'm working on a project in Maven and I'm trying to understand where certain settings are coming from in the effective pom. I want to trace backwards, so I can figure out which pom files need changing. I have modified my parent pom, my settings.xml file, and any other pom that seems to play a part, but the settings I want changed persist in the effective pom.

Is there a way to see where sections of the effective-pom come from? Or, can I at least see the "dependency" chain, if you will, of pom files that go into the effective pom?

Essentially I have a similar problem as this question: How to remove repositories from Effective POM but if there is a way to trace backwards that would really help me out.

Thanks!

Incident answered 16/6, 2015 at 15:40 Comment(0)
M
4

This answer describes the various parts that create the effective POM.

You may try a variation of this answer to view the POM hierarchy (what you called the "dependency" chain). Add this config to the parent POM's <build><plugins> section (temporarily?) to see it.

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>groovy-maven-plugin</artifactId>
    <version>2.0</version>
    <executions>
        <execution>
            <id>echo-build-environment</id>
            <phase>validate</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <source>
                <![CDATA[
                log.info("POM Hierarchy")
                def rootPom = project;
                while (rootPom.parent != null) {
                    log.info(rootPom.groupId + ':' + rootPom.artifactId + ':' + rootPom.version)
                    rootPom = rootPom.parent;
                }
                log.info(rootPom.groupId + ':' + rootPom.artifactId + ':' + rootPom.version)
                ]]>
                </source>
            </configuration>
        </execution>
    </executions>
</plugin>

(Note, in pure Groovy the log.info lines above could be written as

"${rootPom.groupId}:${rootPom.artifactId}:${rootPom.version}"

Groovy calls these GStrings. I know the gmaven plugin handles GStrings a little differently than plain Groovy but don't have time to look up the details right now so used regular string concatenation in the example.)

Marcy answered 16/6, 2015 at 17:1 Comment(2)
Thank you @user944849, although I don't quite understand why when I put this in the <build><plugins> section or the <build><pluginManagement><plugins> section of different POMs, I don't seem to get any output. I'm running "mvn clean install".. I tried "mvn execute" and "mvn validate:execute" but those throw errors. I'm missing some critical knowledge and will have to do some research, unless you're aware of what I'm missing...?Incident
mvn execute & mvn validate:execute won't work. execute is a goal, not a phase. validate:execute means running the execute goal of the validate plugin; which I'm not sure exists. (If you're learning Maven I highly recommend doing some research to understand the difference between phases & goals.) If you have the config in the <build><plugins> section of the parent POM, it should run as part of the validate phase, so mvn validate should do it. If you get no results, try using -X to get debug output.Marcy
P
7

Using a Maven plugin

Since version 3.2.0 of the maven-help-plugin the new verbose flag has been added to the effective-pom goal which will show you this information. Setting verbose to true will add a comment to each line in the output that points to the source POM file. The output does not show you the full dependency chain but it does include the group id, artifact id, version and line number of the source file.

You can generate the verbose effective POM by executing the following Maven command (making sure to use version 3.2.0 or later of the maven-help-plugin):

mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:effective-pom -Dverbose=true

If we apply this to a simple Maven project that inherits from a parent pom like in this example:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.0</version>
  </parent>

  <groupId>org.mycompany</groupId>
  <artifactId>myproject</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>My Project</name>

  <properties>
      <a-property>hello world</a-property>
  </properties>
</project>

Then the output will look like this (notice the additional XML comments at the end of each line):

<?xml version="1.0" encoding="Cp1252"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 5 -->
  <parent>
    <groupId>org.springframework.boot</groupId>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 8 -->
    <artifactId>spring-boot-starter-parent</artifactId>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 9 -->
    <version>2.4.0</version>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 10 -->
  </parent>
  <groupId>org.mycompany</groupId>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 13 -->
  <artifactId>myproject</artifactId>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 14 -->
  <version>1.0-SNAPSHOT</version>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 15 -->
  <name>My Project</name>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 17 -->
  <description>Parent pom providing dependency and plugin management for applications built with Maven</description>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 12 -->
  <url>https://spring.io/projects/spring-boot/myproject</url>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 21 -->
  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 24 -->
      <url>https://www.apache.org/licenses/LICENSE-2.0</url>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 25 -->
    </license>
  </licenses>
  <developers>
    <developer>
      <name>Pivotal</name>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 30 -->
      <email>[email protected]</email>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 31 -->
      <organization>Pivotal Software, Inc.</organization>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 32 -->
      <organizationUrl>https://www.spring.io</organizationUrl>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 33 -->
    </developer>
  </developers>
  <scm>
    <url>https://github.com/spring-projects/spring-boot/myproject</url>  <!-- org.springframework.boot:spring-boot-starter-parent:2.4.0, line 37 -->
  </scm>
  <properties>
    <a-property>hello world</a-property>  <!-- org.mycompany:myproject:1.0-SNAPSHOT, line 20 -->

Using Apache NetBeans

An alternative option is to use the Apache NetBeans IDE which has a feature that annotates the effective POM file with a link to the source of each line.

Open the pom.xml file of your Maven project in the NetBeans IDE and click the "Effective" tab at the top of the editor. By hovering over the annotations on the left side of the editor you can view the source and also click on it to immediately go to the referenced POM file: Source of effective POM in Apache NetBeans

Prochoras answered 2/5, 2021 at 18:22 Comment(0)
M
4

This answer describes the various parts that create the effective POM.

You may try a variation of this answer to view the POM hierarchy (what you called the "dependency" chain). Add this config to the parent POM's <build><plugins> section (temporarily?) to see it.

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>groovy-maven-plugin</artifactId>
    <version>2.0</version>
    <executions>
        <execution>
            <id>echo-build-environment</id>
            <phase>validate</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <source>
                <![CDATA[
                log.info("POM Hierarchy")
                def rootPom = project;
                while (rootPom.parent != null) {
                    log.info(rootPom.groupId + ':' + rootPom.artifactId + ':' + rootPom.version)
                    rootPom = rootPom.parent;
                }
                log.info(rootPom.groupId + ':' + rootPom.artifactId + ':' + rootPom.version)
                ]]>
                </source>
            </configuration>
        </execution>
    </executions>
</plugin>

(Note, in pure Groovy the log.info lines above could be written as

"${rootPom.groupId}:${rootPom.artifactId}:${rootPom.version}"

Groovy calls these GStrings. I know the gmaven plugin handles GStrings a little differently than plain Groovy but don't have time to look up the details right now so used regular string concatenation in the example.)

Marcy answered 16/6, 2015 at 17:1 Comment(2)
Thank you @user944849, although I don't quite understand why when I put this in the <build><plugins> section or the <build><pluginManagement><plugins> section of different POMs, I don't seem to get any output. I'm running "mvn clean install".. I tried "mvn execute" and "mvn validate:execute" but those throw errors. I'm missing some critical knowledge and will have to do some research, unless you're aware of what I'm missing...?Incident
mvn execute & mvn validate:execute won't work. execute is a goal, not a phase. validate:execute means running the execute goal of the validate plugin; which I'm not sure exists. (If you're learning Maven I highly recommend doing some research to understand the difference between phases & goals.) If you have the config in the <build><plugins> section of the parent POM, it should run as part of the validate phase, so mvn validate should do it. If you get no results, try using -X to get debug output.Marcy

© 2022 - 2024 — McMap. All rights reserved.