我最终编写了自己的插件,该插件利用mojo-executor来调用其他 mojo。这使我能够 1) 集中构建配置和 2) 最大限度地减少在每个子项目中重复的配置数量。
(如果您对这一切的原因感到好奇:每个子项目都是一个将从命令行执行的作业。构建设置了一个调用者 shell 脚本并将其附加到构建中,以便将其签入我们的工件存储库。部署脚本稍后将它们拉到它们将运行的机器上。)
模板项目的 pom 的相关部分:
<project ...>
<parent> ... </parent>
<artifactId>job-template</artifactId>
<packaging>pom</packaging>
<name>job project template</name>
<build>
<pluginManagement>
<plugin>
<groupId>...</groupId>
<artifactId>job-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-sources-step</id>
<goals><goal>job-generate-sources</goal></goals>
</execution>
<execution>
<id>package-step</id>
<goals><goal>job-package</goal></goals>
</execution>
... (a couple more executions) ...
</executions>
</plugin>
</pluginManagement>
</build>
</project>
不得不创建一个新的 maven-plugin 项目(job-maven-plugin)。Pom 看起来像:
<project ...>
<parent> ... </parent>
<artifactId>job-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<name>job maven executor plugin</name>
<dependencies>
<dependency>
<groupId>org.twdata.maven</groupId>
<artifactId>mojo-executor</artifactId>
<!-- version 1.5 supports Maven 2, while version 2.0 only supports Maven 3 -->
<version>1.5</version>
</dependency>
</dependencies>
</project>
正如您从模板项目中看到的那样,我的插件中有多个 mojo(每个阶段一个需要发生的事情)。例如,job-package mojo 绑定到 package 阶段并使用 mojo-executor 库来运行另外两个 mojo(它们只是附加了一些构建工件):
/**
* @goal job-package
* @phase package
*/
public class PackageMojo extends AbstractMojo {
/**
* @parameter expression="${project}"
* @required
* @readonly
*/
protected MavenProject project;
/**
* @parameter expression="${session}"
* @required
* @readonly
*/
protected MavenSession session;
/**
* @component
* @required
*/
protected PluginManager pluginManager;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
ExecutionEnvironment environment = executionEnvironment(project, session, pluginManager);
// Attach script as a build artifact
executeMojo(
plugin(
groupId("org.codehaus.mojo"),
artifactId("build-helper-maven-plugin"),
version("1.7")
),
goal("attach-artifact"),
configuration(
element("artifacts",
element("artifact",
element("file", "${project.build.directory}/script.shl"),
element("type", "shl")
)
)
),
environment
);
// Zip up the jar and script as another build artifact
executeMojo(
plugin(
groupId("org.apache.maven.plugins"),
artifactId("maven-assembly-plugin"),
version("2.3")
),
goal("single"),
configuration(
element("descriptors",
element("descriptor", "${project.build.directory}/job/descriptor.xml")
)
),
environment
);
}
}
然后,在子项目中,我只需要引用一次插件。在我看来,这比在每个子项目中重复每个幕后插件要好得多(这不可接受地增加了 pom 之间的耦合)。如果我以后想在构建过程中添加一个 mojo 执行,我只需要修改一个地方并增加一个版本号。子项目的 pom 看起来像:
<project ...>
<parent>
<groupId> ... </groupId>
<artifactId>job-template</artifactId>
<version> ... </version>
<relativePath>../job-template</relativePath>
</parent>
<artifactId>job-testjob</artifactId>
<name>test job</name>
<build>
<plugins>
<plugin>
<groupId> ... </groupId>
<artifactId>job-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
此外,整个多模块目录结构现在看起来像这样:
+- job
+- job-core
+- job-maven-plugin
+- job-template
+- job-testjob1 (inherits from job-template)
+- job-testjob2 (inherits from job-template)
在我看来,这个解决方案并不完全是最佳的,因为我现在将插件配置嵌入到一系列 mojos 而不是 pom 中,但它满足了我的目标,即集中配置并最大限度地减少子项目 pom 之间的重复。
(最后一点:我刚刚发现maven-aggregate-plugin似乎允许在 pom 中对多个插件执行进行分组。这可能以稍微更理想的方式解决了问题,但我没有心情重做最后一个几个小时的工作。虽然可能对其他人有益。)