有趣的问题,我无法判断我是否做错了什么,或者这是Maven的限制。
该方案的最简单版本是存在父 POM、单个子 POM 和聚合 POM。聚合 POM 只是将模块链接在一起。
当我安装聚合 POM 时,它不会找出子 POM 对父 POM 的依赖关系。 我宁愿没有相对路径,从我对Maven工件的理解来看应该是可能的。
任何见解将不胜感激。 谢谢。
这是超级父母(没关系,里面什么都没有)
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my.group</groupId>
<artifactId>parent-uber</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
这是孩子:
<?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>
为了完整起见,聚合器:
<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>
错误:
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
您可以通过添加用于仅构建父级的特殊配置文件来解决此问题。
在您的子 pom 中,将<relativePath />
添加到<parent>
标签中。然后修改聚合器。
聚合器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>
并使用它来运行构建两次,如下所示:
mvn install -Pprepare
mvn install
第一个命令将父级的 pom 安装到本地存储库,因此第二个命令不会失败。
但是,仅当父项目与子项目所需的版本相同时,此解决方案才有效。但是,假设您已经发布了父级的 1.0 版,现在您正在使用 1.1-SNAPSHOT 版本的父级,但子级使用的是已发布的 1.0 版。如果现在要删除本地存储库,或者其他人将克隆您的项目,则使用 -Pprepare
进行构建将不起作用,因为这将安装parent-uber:1.1-SNAPSHOT
并且子项仍将具有未解决的依赖项。
因此,要使其正常工作,您需要有一个外部存储库(nexus,artifactory等),parent-uber:1.0
并且您必须在子pom <repositories>
标签中提供此存储库。
当有很多子项目时,通常最好将通用设置放入父 pom 中,以避免重复代码。由于存储库对于所有项目都是通用的,因此您可能希望将其放在父项目中。但是,如果您没有在本地安装父级并尝试安装子级,那么 maven 不知道它应该使用哪个存储库来下载父级。为避免此问题,您可以将该存储库的配置文件添加到.m2/settings.xml
中,并建议所有团队成员也这样做。
根据该指南,似乎 maven 多模块反应器不会自动分析父依赖关系。由于列表中未列出父依赖项。
对项目进行排序时,将遵循以下关系:
- 对生成中另一个模块的项目依赖关系
插件- 声明,其中插件是构建中的另一个模块
- 插件对构建中另一个模块的依赖
生成- 中另一个模块上的生成扩展声明元素中声明的顺序(如果没有其他规则适用)
我验证了 maven 确实通过分析子模块之间由标签定义的依赖关系图来确定构建顺序。
这是否是您问题的解决方案,但是:
指定父 pom 时,maven 默认假定它位于父文件夹中。这不是你的情况,所以你必须重新定义父java的父部分中的相对路径以指向../parent-uber
,pom将在本地解析,或作为<relativePath />
解析,并且它将远程解析。
在我的情况下,定义的父pom版本与我在子pom中提到的版本不同,因此出现了错误。一旦我更正了父pom上的版本,它就开始正常工作.xml -
<version>2.1.0</version>
子 pom 条目看起来像
<relativePath>../parent-pom</relativePath>
好吧,我以另一种方式做到了这一点。
就我而言,我想要一个"父级",它也是一个"聚合器"。
因此,我创建了我的项目"父+聚合器"。
这是我的项目"父+聚合器"的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>
在此之后,我将"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>
因此,当我在没有配置文件或使用"干净安装本地"配置文件的情况下构建"testproject"(父测试项目)时,所有项目都会被构建,包括父项目。
当我使用配置文件"deployArchiva"构建"testproject"(父测试项目)时,只有项目本身被构建并部署到Archiva。
我希望它有用。