Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 262
Duff Avatar asked Jun 16 '15 15:06

Duff


2 Answers

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

like image 109
user1660326 Avatar answered Nov 18 '22 18:11

user1660326


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.)

like image 4
user944849 Avatar answered Nov 18 '22 18:11

user944849