Inheritance 让Maven聚合器pom将属性注入模块pom的可行性(不使用继承)

Inheritance 让Maven聚合器pom将属性注入模块pom的可行性(不使用继承),inheritance,properties,maven,aggregate,multi-module,Inheritance,Properties,Maven,Aggregate,Multi Module,关于Maven,我想问你一个可行性问题。特别是,我们是否可以在聚合pom中定义属性,然后将它们注入到引用的模块中,从而允许该模块本地覆盖在继承层次结构中定义的默认属性 如果您对细节感兴趣,我将描述我的设置。在我这么做之前,我想说的是,我们已经作为一个团队广泛地讨论了我们的项目结构,它非常适合我们的需要。在这一点上,我们不是在寻找关于其他结构的建议,而是专门探讨maven是否能够满足我们的需求 那么我们的设置,;我将把它归结为要点。我们有两个源项目,A和B。每一个都是另一个的子模块,分别是Pare

关于Maven,我想问你一个可行性问题。特别是,我们是否可以在聚合pom中定义属性,然后将它们注入到引用的模块中,从而允许该模块本地覆盖在继承层次结构中定义的默认属性

如果您对细节感兴趣,我将描述我的设置。在我这么做之前,我想说的是,我们已经作为一个团队广泛地讨论了我们的项目结构,它非常适合我们的需要。在这一点上,我们不是在寻找关于其他结构的建议,而是专门探讨maven是否能够满足我们的需求

那么我们的设置,;我将把它归结为要点。我们有两个源项目,A和B。每一个都是另一个的子模块,分别是ParentA和ParentB。从技术上讲,ParentA和ParentB有许多子模块,但在本例中,为了简单起见,我只会显式地引用每个子模块。到现在为止,一直都还不错。ParentA引用A作为子模块,A引用ParentA作为其父模块。同样的关系也适用于B和ParentB之间

现在,乐趣来了。我们希望ParentA和ParentB都有一个超级父pom来继承共享属性和配置,如dependencyManagement和插件等。但我们不希望这个超级父pom负责构建。相反,我们想定义一些构建项目,它们选择性地构建各种模块。在这个例子中,我将介绍BuildAB和BuildB。第一个构建了A,然后构建了B,而第二个构建了B。实际上,我们有很多交错的模块组和依赖项。最后,为了完成这幅图,我们有一个从B到a的依赖关系

让我试着用一些ascii艺术画出来;)

继承权

A --> ParentA --> parent
B --> ParentB --> parent
子模块关系

BuildAB ==> { (ParentA ==> A) (ParentB ==> B) }
BuildB ==> (ParentB ==> B)
依赖关系

B > A
现在,就目前情况而言,不可能使用BuildAB和BuildB文件中的属性来定义依赖关系;这些构建文件不是任何继承树的一部分,因此没有任何内容会获取属性。但是我们确实希望在运行BuildAB和BuildB时以不同的方式控制依赖版本;简单地将依赖项放在超级父项中并不能满足我们的需求

如果你想知道为什么这会被认为是一个团队可能正在开发B模块,也可能对A做一些小的修改。其他开发人员可能正在为项目A开发最新和最伟大的项目,由于依赖性,该项目对B产生了影响。多亏了Mercurial,我们在源代码中有很好的处理机制。但我们真的很难与Maven合作

理想情况下,每个构建文件首先依赖于从父级继承的子模块。但是,当我们需要重写此继承时,我们希望能够在构建文件中指定可注入属性,这将与最初在模块中指定的属性完全相同。当然,所有这些都不需要实际修改pom,因为pom是源代码控制的

我们想评估的是,是否有任何范围可以通过插件或补丁修改maven来实现这一点

我们以前从未编写过插件(坦率地说,关于这方面的在线教程和内容很少,而且对开发人员并不友好——除非有人有一个我错过的好教程:),但如果它看起来可行,我们愿意尝试一下

所以基本上

  • 您以前是否自己处理过类似的需求,并使其与现有插件一起工作
  • 有没有一个简单的把戏我们错过了
  • 你有没有写过类似的插件,可以推荐一个开始的地方
  • 你知道这样一个插件不起作用的实际原因吗
  • 您是否在maven源代码上工作,并且知道我们是否能够提供任何结果代码。。。如果我们愿意,我们应该从哪里开始寻找
最后一点意见。我们在Eclipse中开发,因此我们还需要构建在没有属性注入的情况下工作。我希望这是通过正常的继承树实现的

非常感谢大家,我知道这是一个有点棘手的问题。

对于各种特殊魔法:使用maven构建扩展

这是一个不知名的(和maven一样,叹气)没有很好记录的机制,但就我所见,它确实是一种官方认可的方式,可以影响整个构建过程

import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;

@Component(role = AbstractMavenLifecycleParticipant.class, hint = "mySpecialService")
public class MySpecialExtension
    extends AbstractMavenLifecycleParticipant
{

    @Requirement
    private Logger logger;

    @Override
    public void afterProjectsRead( MavenSession session ) {
        // ...do you magic here

        // for example, to set some POM properties
        Properties sysProps = session.getSystemProperties();
        ....
        Properties projProps = session.getCurrentProject().getProperties();
        projProps.setProperty("..",val);
在解析pom.xml文件并在内存中构建基本pom之后,但在任何进一步的构建活动开始之前,立即调用此函数。在多模块项目中,从根项目调用扩展,即使它仅在某个子模块中定义。在这一点上,理论上你可以在构建过程中做任何事情,比如将一些属性注入pom,从artefact manager加载更多的项目,并将它们添加到构建反应器,查找一些特定的插件,重塑某些模块的pom,甚至构建没有在任何地方声明的东西(!)

要构建这样的扩展,您需要将代码放入一个单独的maven项目中

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <prerequisites>
        <maven>3.0</maven>
    </prerequisites>

    <name>my-special-service</name>
    <groupId>my.group</groupId>
    <artifactId>my-special-service</artifactId>
    <packaging>jar</packaging>

    <parent>
       ....
    </parent>

    <properties>
        <mavenApiVer>3.0.5</mavenApiVer>
        <mavenModelVer>2.2.1</mavenModelVer>
    </properties>

<build>
    <plugins>
        <!-- Maven Build Extension -->
        <plugin>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-component-metadata</artifactId>
            <version>1.5.5</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-metadata</goal>
                        <!-- goal>generate-test-metadata</goal -->
                    </goals>
                </execution>
            </executions>
            </plugin>
            <!-- Maven Build Extension -->
        </plugins>
    </build>


    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-project</artifactId>
            <version>${mavenModelVer}</version>
        </dependency>

        <!-- Maven Build Extension -->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-compat</artifactId>
            <version>${mavenApiVer}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
            <version>${mavenApiVer}</version>
        </dependency>
        <!-- Maven Build Extension -->

        ....

    </dependencies>
</project>

4.0.0
3
我的特别服务
我的团队
我的特别服务
罐子
....
3.0.5
2.2.1
org.codehaus.plexus
丛组件元数据
1.5.5
生成元数据
org.apache.maven
马文项目
${mavenModelVer}
org.apache.maven
马文同胞
${mavenApiVer}
<build>
    <extensions>
        <extension><!-- Maven Build Extension: my Special Service -->
            <groupId>my.group</groupId>
            <artifactId>my-special-service</artifactId>
            <version>.....</version>
        </extension>
    </extensions>

    <pluginManagement>
    ....