Maven doesn't resolve local parent POM

20,043

Solution 1

You can solve this problem by adding special profile for building only parent.

In your child pom add <relativePath /> to the <parent> tag. Then modify aggregator.

Aggregator pom:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>my.group.maven</groupId>
    <artifactId>_poms-aggregator</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <modules>
                <module>parent-uber</module>
                <module>parent-java</module>
            </modules>
        </profile>
        <profile>
            <id>prepare</id>
            <modules>
                <module>parent-uber</module>
            </modules>
        </profile>
    </profiles>

</project>

And use it to run build twice, like that:

mvn install -Pprepare
mvn install

First command installs parent's pom to local repo, so the second command will not fail.

But this solution works only if your parent project has the same version as the one that child needs. But let's say that you've released version 1.0 of parent and now you're working on parent with 1.1-SNAPSHOT version but child uses the released version 1.0. If you'll now delete your local repo, or someone else will clone your project, building with -Pprepare won't work, as this will install parent-uber:1.1-SNAPSHOT and child will still have unresolved dependency.

So for this to work you'll need to have an external repository (nexus, artifactory etc) into which you've released parent-uber:1.0 and you'll have to provide this repo in <repositories> tag in child pom.

When there's a lot of child projects it's often a good idea to put common settings into parent pom, to avoid duplicating code. As repository is common to all projects you may want to put it in parent. But then, if you don't have parent locally installed and try to install child, then maven doesn't know which repository it should use to download the parent. To avoid this problem you can add profile with that repository into .m2/settings.xml and advice all your team members to do the same.

Solution 2

According to this guideline, seems parent dependency is NOT automatically analyzed by maven multi-modules reactor. Since NO parent dependency is listed in the list.

The following relationships are honoured when sorting projects:

  1. project dependency on another module in the build
  2. plugin declaration where the plugin is another modules in the build
  3. plugin dependency on another module in the build
  4. build extension declaration on another module in the build the order declared in the element (if no other rule applies)

And I verified maven indeed determines the build order by analyzing the dependency graph, defined by tags, between submodules .

Share:
20,043
Thomas Beauvais
Author by

Thomas Beauvais

A web application developer for 10 years with emphasis in the server-client technologies needed to support massive distribution/contribution networks.

Updated on July 09, 2022

Comments

  • Thomas Beauvais
    Thomas Beauvais almost 2 years

    This is an interesting problem and I can't tell if I am doing something wrong or it's a limitation of Maven.

    The simplest version of the scenario is that there is a parent POM, single child POM, and an aggregation POM. The aggregation POM is merely to chain the modules together.

    When I install the aggregation POM, it doesn't find out the dependencies of the child POM on the parent POM. I would prefer not to have a relative path and should be possible from my understanding of Maven artifacts.

    Any insight would be greatly appreciated. Thanks.

    This is the uber parent (never mind that there is nothing in it)

    <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>my.group</groupId>
        <artifactId>parent-uber</artifactId>
        <version>0.0.2-SNAPSHOT</version>
        <packaging>pom</packaging>
    
    </project>
    

    This is the child:

    <?xml version="1.0" encoding="UTF-8"?>
    <project>
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>my.group</groupId>
            <artifactId>parent-uber</artifactId>
            <version>0.0.2-SNAPSHOT</version>
        </parent>
    
        <groupId>my.group</groupId>
        <artifactId>parent-java</artifactId>
        <packaging>pom</packaging>
    
        <properties>
        </properties>
    
        <build>
            <!-- To define the plugin version in your parent POM -->
            <pluginManagement>
                <plugins>
                    <!-- All projects that extend this should have valid JavaDoc built-->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>attach-javadocs</id>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.11</version>
                    <scope>test</scope>
                </dependency>    
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>1.2.17</version>
                </dependency>    
                <dependency>
                    <groupId>commons-lang</groupId>
                    <artifactId>commons-lang</artifactId>
                    <version>2.1</version>
                </dependency>    
                <dependency>
                    <groupId>commons-io</groupId>
                    <artifactId>commons-io</artifactId>
                    <version>2.4</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
    

    And for completeness, the aggregator:

    <project>
        <modelVersion>4.0.0</modelVersion>
    
        <parent>
            <groupId>my.group</groupId>
            <artifactId>_maven-integration-aggregator</artifactId>
            <version>0.1-SNAPSHOT</version>
            <relativePath>../pom.xml</relativePath> <!-- parent aggregator -->
        </parent>
    
        <groupId>my.group.maven</groupId>
        <artifactId>_poms-aggregator</artifactId>
        <version>0.1-SNAPSHOT</version>
        <packaging>pom</packaging>
    
        <modules>
            <module>parent-uber</module>
            <module>parent-java</module>
        </modules>
    
    </project>
    

    The error:

    org.apache.maven.model.resolution.UnresolvableModelException: Could not find artifact my.group:parent-uber:pom:0.0.2-SNAPSHOT
        at org.apache.maven.project.ProjectModelResolver.resolveModel(ProjectModelResolver.java:159)
        at org.apache.maven.model.building.DefaultModelBuilder.readParentExternally(DefaultModelBuilder.java:817)
        at org.apache.maven.model.building.DefaultModelBuilder.readParent(DefaultModelBuilder.java:669)
        at org.apache.maven.model.building.DefaultModelBuilder.build(DefaultModelBuilder.java:307)
        at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:411)
        at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:380)
        at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:496)
        at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:380)
        at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:344)
        at org.apache.maven.DefaultMaven.collectProjects(DefaultMaven.java:637)
        at org.apache.maven.DefaultMaven.getProjectsForMavenReactor(DefaultMaven.java:586)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:229)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:152)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:555)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact my.group:parent-uber:pom:0.0.2-SNAPSHOT
        at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:459)
        at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:262)
        at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:239)
        at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:295)
        at org.apache.maven.project.ProjectModelResolver.resolveModel(ProjectModelResolver.java:155)
        ... 23 more
    Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact my.parent:parent-uber:pom:0.0.2-SNAPSHOT
        at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:449)
        ... 27 more
    
  • Thomas Beauvais
    Thomas Beauvais over 10 years
    This is a problem because it is forcing you to organize all of the projects within the context of the parent dependencies. This really isn't want I am looking for. I want to be able to extend parent functionality (dependencies, plugins, etc) and resolve the POM via our repository. I generally understand the rigid well defined structure of Maven, but this is going a bit too far. If I have a new clean project that uses the parent-uber or parent-java then it should simply download/resolve that dependency. It will resolve it if I 'mvn install' in the child project again after the error.
  • Thomas Beauvais
    Thomas Beauvais over 10 years
    I understand that my comment conflates two issues. So I will clarify. I simply want to know if there is a way to resolve the POM structure without hard coding the relative paths. Maven has the information to resolve this in the repo but isn't.
  • diegomtassis
    diegomtassis over 10 years
    Have you tried with <relativePath /> in your parent declaration?
  • Thomas Beauvais
    Thomas Beauvais over 10 years
    The idea is that I want to provide a set of parent POMs as easily extendable to provide the necessary dependencies and plugin declarations by default. Thus, it doesn't mat since to have a <relativePath/> empty or otherwise. If it does, can you please explain a little more so that I might try it and understand the result?