你怎么强迫maven MOJO在构建结束时只执行一次?

时间:2008-09-25 12:24:31

标签: java maven-2 maven-plugin mojo

我有一个MOJO我想执行一次,并且只在反应堆中最后一个项目的测试阶段之后运行。

使用:

if (!getProject().isExecutionRoot()) {
        return ;
}

在execute()方法的开头意味着我的mojo被执行一次,但是在构建的最开始 - 在所有其他子模块之前。

8 个答案:

答案 0 :(得分:9)

我找到的最佳解决方案是:

/**
 * The projects in the reactor.
 *
 * @parameter expression="${reactorProjects}"
 * @readonly
 */
private List reactorProjects;

public void execute() throws MojoExecutionException {

    // only execute this mojo once, on the very last project in the reactor
    final int size = reactorProjects.size();
    MavenProject lastProject = (MavenProject) reactorProjects.get(size - 1);
    if (lastProject != getProject()) {
        return;
    }
   // do work
   ...
}

这似乎适用于我测试过的小型构建层次结构。

答案 1 :(得分:3)

最佳解决方案是依靠生命周期扩展,方法是从org.apache.maven.AbstractMavenLifecycleParticipant扩展您的课程(另请参阅https://maven.apache.org/examples/maven-3-lifecycle-extensions.html),该方法afterSessionEnd添加了https://issues.apache.org/jira/browse/MNG-5640(已修复) Maven 3.2.2)。

答案 2 :(得分:2)

有一个Sonatype blog entry描述了如何执行此操作。要运行的最后一个项目将是根项目,因为它将包含对其余项目的模块引用。因此,您需要在mojo中进行测试,以检查当前项目的目录是否与Maven的启动目录相同:

boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());

在引用的条目中有一个非常全面的例子,说明如何在你的mojo中使用它。

答案 3 :(得分:1)

我认为如果您使用 @aggregator 标记并将mojo绑定到以下生命周期阶段之一,您可能会得到所需内容:

  • 制备封装
  • 预集成测试
  • 集成测试
  • 整后试验
  • 验证
  • 安装
  • 部署

答案 4 :(得分:1)

使用session.getEventDispatcher()的解决方案自Maven 3.x起不再有效。整个事件已在此提交中删除:https://github.com/apache/maven/commit/505423e666b9a8814e1c1aa5d50f4e73b8d710f4

答案 5 :(得分:0)

查看maven-monitor API

您可以将EventMonitor添加到调度程序,然后捕获'reactor-execute'事件的END:在完成所有操作后调度,即使在您看到BUILD SUCCESSFUL / FAILED输出后也是如此。

以下是我最近如何使用它在最后打印摘要:

/**
 * The Maven Project Object
 *
 * @parameter expression="${project}"
 * @required
 * @readonly
 */
protected MavenProject project;


/**
 * The Maven Session.
 *
 * @parameter expression="${session}"
 * @required
 * @readonly
 */
protected MavenSession session;

...


@Override
public void execute() throws MojoExecutionException, MojoFailureException
{
    //Register the event handler right at the start only
    if (project.isExecutionRoot())
        registerEventMonitor();
    ...
}


/**
 * Register an {@link EventMonitor} with Maven so that we can respond to certain lifecycle events
 */
protected void registerEventMonitor()
{
    session.getEventDispatcher().addEventMonitor(
            new EventMonitor() {

                @Override
                public void endEvent(String eventName, String target, long arg2) {
                    if (eventName.equals("reactor-execute"))
                        printSummary();
                }

                @Override
                public void startEvent(String eventName, String target, long arg2) {}

                @Override
                public void errorEvent(String eventName, String target, long arg2, Throwable arg3) {}


            }
    );
}


/**
 * Print summary at end
 */
protected void printSummary()
{
    ...
}

答案 6 :(得分:0)

你可以使用 mavensession 来解决这个问题

public boolean isThisTheLastProject() {
        return session.getProjectDependencyGraph().getSortedProjects().
                get(session.getProjectDependencyGraph().getSortedProjects().size()-1).getArtifactId().equalsIgnoreCase(project.getArtifactId());
    }

答案 7 :(得分:-1)

通常,这是配置问题。您可能必须为mojo设置项目并使其依赖于所有其他项目。或者你可以强迫其中一个子项目成为最后一个,让它依赖于所有其他孩子。