Java Maven 不解析本地父 POM

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19765833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:02:23  来源:igfitidea点击:

Maven doesn't resolve local parent POM

javamavenpom.xmlparent-pom

提问by Thomas Beauvais

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

这是一个有趣的问题,我不知道是我做错了什么还是 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.

该场景的最简单版本是有一个父 POM、单个子 POM 和一个聚合 POM。聚合 POM 只是将模块链接在一起。

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.

当我安装聚合 POM 时,它没有找出子 POM 对父 POM 的依赖关系。我不希望有相对路径,根据我对 Maven 工件的理解应该是可能的。

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

回答by diegomtassis

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.

指定父 pom 时,maven默认假定它位于父文件夹中。这不是您的情况,因此您必须重新定义 parent-java 的 parent 部分中的相对路径以指向../parent-uber,pom 将在本地解析,或者作为<relativePath />,它将远程解析。

回答by Gautam

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 -

就我而言,定义的父 pom 版本与我在子 pom 中提到的版本不同,因此出现错误。一旦我更正了父 pom.xml 上的版本,它就开始正常工作 -

<version>2.1.0</version>

child pom entry looked like

儿童 pom 条目看起来像

<relativePath>../parent-pom</relativePath>

回答by bartnikiewi.cz

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.

在您的孩子 pom 添加<relativePath /><parent>标签。然后修改聚合器。

Aggregator pom:

聚合器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.

第一个命令将父级的 pom 安装到本地 repo,因此第二个命令不会失败。

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 -Ppreparewon't work, as this will install parent-uber:1.1-SNAPSHOTand child will still have unresolved dependency.

但只有当您的父项目与子项目具有相同的版本时,此解决方案才有效。但是假设您已经发布了 parent 1.0 版,现在您正在使用 1.1-SNAPSHOT 版本处理 parent,但 child 使用已发布的 1.0 版。如果您现在要删除本地存储库,或者其他人将克隆您的项目,则构建-Pprepare将不起作用,因为这将安装parent-uber:1.1-SNAPSHOT并且子项仍将具有未解决的依赖项。

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

因此,要使其正常工作,您需要拥有一个已发布到其中的外部存储库(nexus、artifactory 等),parent-uber:1.0并且您必须<repositories>在子 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.xmland advice all your team members to do the same.

当有很多子项目时,将公共设置放入父 pom 中通常是个好主意,以避免重复代码。由于存储库对所有项目都是通用的,您可能希望将其放在父级中。但是,如果您没有在本地安装 parent 并尝试安装 child,那么 maven 不知道它应该使用哪个存储库来下载 parent。为了避免这个问题,您可以将包含该存储库的配置文件添加到.m2/settings.xml并建议您的所有团队成员也这样做。

回答by Popeye

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.

根据此指南,maven 多模块反应器似乎不会自动分析父依赖项。由于列表中未列出父依赖项。

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)

排序项目时遵循以下关系:

  1. 项目依赖于构建中的另一个模块
  2. 插件声明,其中插件是构建中的另一个模块
  3. 插件依赖于构建中的另一个模块
  4. 在构建中的另一个模块上构建扩展声明元素中声明的顺序(如果没有其他规则适用)

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

我验证了 maven 确实通过分析子模块之间由标签定义的依赖关系图来确定构建顺序。

回答by Cezar Oliveira

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":

这是从我的项目“父+聚合器”的 pom.xml 中截取的:

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

在此之后,我将“testprojectejb”更改为引用“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.

因此,当我在没有配置文件或使用“ clean-install-local”配置文件的情况下构建“testproject”(父测试项目)时,将构建所有项目,包括父项目。

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

当我使用配置文件“ deployArchiva”构建“testproject”(父测试项目)时,只会构建项目本身并将其部署到Archiva。

I hope it's useful.

我希望它有用。