'parent.relativePath' of imported bill-of materials POM creating warning in Eclipse

1.4k Views Asked by At

Note that this question is about a parent.relativePath warning in an imported bill-of-materials (BOM), not in the hierarchy of my own POM as with 'parent.relativePath' points at my com.mycompany:MyProject instead of org.apache:apache - Why?.

In Eclipse EE 2022-09 using Java 17 I have a a project with a main POM that extends from our own root POM:

<parent>
  <groupId>com.globalmentor</groupId>
  <artifactId>globalmentor-root</artifactId>
  <version>0.8.13</version>
</parent>

The main POM also brings in dependencies from a bill of materials POM (which we also published):

<dependency>
  <groupId>io.clogr</groupId>
  <artifactId>clogr-bom</artifactId>
  <version>0.8.3</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

When viewing the POM as source, Eclipse shows this warning:

'parent.relativePath' of POM io.clogr:clogr-bom:0.8.3 points at io.clogr:clogr-bom instead of com.globalmentor:globalmentor-base, please verify your project structure pom.xml /foo-bar

(In case it is relevant, note that I also have the actual source of io.clogr:clogr-bom imported into Eclipse as a separate project.)

I am aware of the purpose of relativePath as used in my own POM and parent POM. But this warning seems to be saying that the it doesn't like the relativePath designation of the imported BOM! Nevertheless the warning references line 5 of my main POM, which is the designation of the parent POM (com.globalmentor:globalmentor-root). Moreover look closely at the error message: it says that the relative path of io.clogr:clogr-bom points to itself! This cannot be the case, as io.clogr:clogr-bom has no relative path designation, and the default I understand is ../pom.xml. There is no way I can think of that io.clogr:clogr-bom could have its relative path pointing at io.clogr:clogr-bom itself.

  1. Why is there a warning for the relativePath of an imported BOM, yet the warning references the line for the parent POM coordinates?
  2. How do I fix this: by publishing a new io.clog:clogr-bom using <relativePath />?
  3. But if I publish a new a new io.clog:clogr-bom using <relativePath />, does that mean the children of io.clog:clogr-bom need to add an explicit <relativePath>../pom.xml</relativePath> on the aggregated children of io.clog:clogr-bom because they are now inheriting a relative path from io.clog:clogr-bom, or will they stil get a default of <relativePath>../pom.xml</relativePath> because the relative path does not inherit?
1

There are 1 best solutions below

8
Andrey B. Panfilov On

Eclipse is right: your bom is incorrect, let's elaborate that...

  1. in order to build module pom (project object model, do not confuse with pom.xml) maven needs to know where the parent pom.xml is located (if parent is specified), and here we may raise a question: why do we need to specify both parent GAV coordinates (group-artifact-version) and relativePath? And the rationale is following:

    • maven may locate artifact using GAV coordinates only when that artifact was installed/published in local/remote repository, if that didn't happen maven obviously fails (example: we are bootstrapping new multi-module project)
    • technically, there is no strict requirement to publish parent pom files (for example, parent/aggregator pom files may contain some information about our build process and we do not want to expose such information), moreover, there is no requirement for parent modules to be a part of reactor, however in that case you must use flatten-maven-plugin when installing/publishing such artifacts
  2. maven resolves parent's pom.xml using following algorithm:

    • if relativePath is "specified" maven uses it, please note, the absence of relativePath element means that relativePath is ../pom.xml (that is your case) - to nullify the value of relativePath you need to place <relativePath/> element into parent configuration
    • otherwise maven tries to locate parent pom.xml using GAV coordinates in local repository and in case of failure in remote repositories
  3. so, the general recommendations when dealing with parents are following:

    • if parent module is a part of multi-module project set the correct value of relativePath (relying on default ../pom.xml is not good idea though)
    • if parent module is a not part of multi-module project nullify relativePath via specifying <relativePath/>
    • take advantage of flatten-maven-plugin

In regard to your clogr-bom - that is definitely not a Bill Of Materials, it is just a published aggregator module, in order to be a bom it's content should be following:

 <groupId>io.clogr</groupId>
 <artifactId>clogr-bom</artifactId>
 <version>0.8.3</version>
 <packaging>pom</packaging>

 <name>Clogr BOM</name>
 <description>Parent POM and bill of materials of all Clogr projects.</description>
 <url>https://clogr.io/</url>
 <inceptionYear>2016</inceptionYear>

 <licenses>
  <license>
   <name>Apache-2.0</name>
   <url>https://www.apache.org/licenses/LICENSE-2.0</url>
   <distribution>repo</distribution>
  </license>
 </licenses>

 <organization>
  <name>GlobalMentor, Inc.</name>
  <url>https://www.globalmentor.com/</url>
 </organization>

 <developers>
  …
 </developers>

 <scm>
  <connection>scm:git:https://bitbucket.org/globalmentor/clogr.git</connection>
  <developerConnection>scm:git:https://bitbucket.org/globalmentor/clogr.git</developerConnection>
  <url>https://bitbucket.org/globalmentor/clogr</url>
 </scm>

 <dependencyManagement>
  <dependencies>
   <dependency>
    <groupId>io.clogr</groupId>
    <artifactId>clogr</artifactId>
    <version>0.8.3</version>
   </dependency>

   <dependency>
    <groupId>io.clogr</groupId>
    <artifactId>clogr-logback</artifactId>
    <version>0.8.3</version>
   </dependency>

   <dependency>
    <groupId>io.clogr</groupId>
    <artifactId>clogr-logback-provider</artifactId>
    <version>0.8.3</version>
   </dependency>

   <dependency>
    <groupId>io.clogr</groupId>
    <artifactId>slf4j1-shim</artifactId>
    <version>0.8.3</version>
   </dependency>

  </dependencies>
 </dependencyManagement>


UPD.

Q: Thus any POM that will be published as a parent POM or to be imported needs <relativePath/>

A: My opinion on that is following: any published artifact, which is not intended to be parent in any project must strip-off information about parent (that is not just about relativePath element, but about the entire parent element), the rationale is following:

when we consume external dependency, the only information which makes sense for us is it's transitive dependencies, on the other hand specifying parent in external dependency forces maven to resolve that parent as well, and, unfortunately, that process is error-prone because parent may reside in unreachable repository, may contain mistakes, etc - such glitches are pretty common for projects, which we are considering now as "legacy", however, anything what we are doing now will eventually turn into "legacy" as well.

Q: Who says an aggregate POM cannot also serve as a bill of materials by being imported into another project?

A: I do :) Well, actually there is no common opinion about "what is BoM" even across maven team, however I would prefer to share my opinion with Robert Scholte and consider "BoM" as a "Table Of Contents":

To me a BOM represents only the set of modules of a multimodule, that contain the versions that work together. This should prevent issues with dependency depth/distance which could pull in an unexpected version. Ideally all multimodules also provide a BOM. Other dependencies don't belong here, as they should be upgradable/downgradable independent of the BOM.