Maven doesn't resolve local parent POM
Asked Answered
P

5

7

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
Pete answered 4/11, 2013 at 10:32 Comment(7)
Stupid question: did you install the parent-uber pom?Qualification
Try removing the child <module>parent-java</module>. I guess Maven will still follow it via parent-uberDecasyllabic
The goal is to have both of them listed in the aggregator and have maven understand the dependency on parent-uber. So no, I didn't install the uber-parent. I want to install both parent-uber and parent-java at the same time or at least automatically for my super-root-aggregator (not shown)Pete
Is your parent available on the default location relative to your child? Otherwise, try adding a relativePath for the parent in your child pom.Caundra
This may be a possibility, but I was hoping that Maven was smart enough to figure out the dependency automatically without hardcoding a relative path.Pete
I still think you can remove parent-java from the aggregator and all will be built. Did you even try?Decasyllabic
were you able to fix this using relativePath ?Ackack
S
4

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.

Septic answered 19/2, 2017 at 2:47 Comment(0)
M
1

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 .

Mohan answered 20/7, 2017 at 10:12 Comment(0)
A
0

I don't know whether this is the solution to your problem, but:

When specifying a parent pom, maven by default assumes it's located in the parent folder. This is not your case, so you have either to redefine the relative path in the parent section of your parent-java to point to ../parent-uber, and the pom will be resolved locally, or as <relativePath />, and it will be resolved remotely.

Attitude answered 5/11, 2013 at 10:1 Comment(4)
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.Pete
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.Pete
Have you tried with <relativePath /> in your parent declaration?Attitude
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?Pete
A
0

In my case the parent pom version defined was not the same as the one I mentioned in the child pom and hence the error. It started working fine as soon as I corrected the version on my parent pom.xml -

<version>2.1.0</version>

child pom entry looked like

<relativePath>../parent-pom</relativePath>
Acetic answered 7/8, 2014 at 4:16 Comment(0)
R
0

Well, I did this in another way.

In my case, I wanted a "parent" that is a "aggregator" too.

So, I created my project "parent + aggregator".

This is a snipped from pom.xml of my project "parent + aggregator":

<parent>
    <groupId>com.test</groupId>
    <artifactId>project-sti</artifactId>
    <version>2.4</version>
</parent>

<groupId>com.test</groupId>
<artifactId>parent-testproject</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<profiles>
    <profile>
        <!-- Profile executed during upload to Archiva. Defined in the "parent". -->
        <id>deployArchiva</id>
        <activation>
            <activeByDefault>false</activeByDefault>
        </activation>
        <!-- Necessary to avoid that during "deploy" ocurrs the compilation of the others modules. 
            It's necessary because the tag "activeByDefault=true" works only inside of scope of 
            "pom.xml" of project itself. Therefore, it doesn't consider the profile defined in 
            the "parent". -->
    </profile>
    <profile>
        <!-- Profile executed during the local build (Clean Install). -->
        <id>clean-install-local</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <!-- The order of projects are indifferent, because Maven identify the correct order to 
            compile the projects. -->
        <modules>
            <module>../testprojectjpa</module>
            <module>../testprojectejb</module>
            <module>../testprojectweb</module>
            <module>../testprojectapp</module>
        </modules>
    </profile>
</profiles>

<properties>
    <xstream.version>1.4.9</xstream.version>
    <dom4j.version>1.6.1</dom4j.version>
    <commons-lang.version>2.6</commons-lang.version>
    <commons-io.version>2.2</commons-io.version>
    <commons-beanutils.version>1.9.2</commons-beanutils.version>
    <commons-logging.version>1.1.2</commons-logging.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>${xstream.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>${dom4j.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>${commons-lang.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>${commons-io.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>${commons-beanutils.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>${commons-logging.version}</version>
        <exclusions>
            <exclusion>
                <groupId>*</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

After this, I changed the "testprojectejb" to reference the "parent-testproject".

    <parent>
        <groupId>com.test</groupId>
        <artifactId>parent-testproject</artifactId>
        <version>1.0.0</version>
        <!-- Find the project "parent + aggregator" that was compiled before of 
        the project testprojectejb -->
        <relativePath>../testproject/pom.xml</relativePath>
    </parent>

    <artifactId>testprojectejb</artifactId>
    <packaging>ejb</packaging>
    <name>Projeto testproject ejb</name>
    <version>1.0.0</version>

So, when I build the "testproject" (parent-testproject) without profile or using "clean-install-local" profile, then all the projects are build, including the parent.

When I build "testproject" (parent-testproject) using profile "deployArchiva", then only the project itself is build and deployed to Archiva.

I hope it's useful.

Reputation answered 15/4, 2019 at 16:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.