Как вы заставляете maven MOJO выполняться только один раз в конце сборки? - PullRequest
10 голосов
/ 25 сентября 2008

У меня есть MOJO, который я хотел бы выполнить один раз, и только один раз после фазы тестирования последнего проекта в реакторе для запуска.

Использование:

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

в начале метода execute () означает, что мой mojo выполняется один раз, однако в самом начале сборки - перед всеми другими дочерними модулями.

Ответы [ 7 ]

9 голосов
/ 26 сентября 2008

Лучшее решение, которое я нашел для этого:

/**
 * 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
   ...
}

Похоже, что это работает на небольших иерархиях сборки, с которыми я тестировал.

3 голосов
/ 13 октября 2016

Лучшим решением является расширение жизненного цикла путем расширения вашего класса с 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 голосов
/ 28 июля 2009

В блоге Sonatype есть запись , в которой описано, как это сделать. Последним проектом, который будет запущен, будет корневой проект, поскольку он будет содержать ссылки на остальные модули. Следовательно, вам нужен тест в вашем mojo, чтобы проверить, совпадает ли каталог текущего проекта с каталогом, из которого был запущен Maven:

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

В ссылочной записи есть довольно полный пример того, как использовать это в вашем моджо.

1 голос
/ 19 августа 2016

Решение с использованием session.getEventDispatcher () больше не работает с Maven 3.x. Все события были удалены в этом коммите: https://github.com/apache/maven/commit/505423e666b9a8814e1c1aa5d50f4e73b8d710f4

1 голос
/ 25 сентября 2008

Я думаю, вы можете получить то, что вам нужно, если вы используете тег @ aggregator и привязываете mojo к одному из следующих этапов жизненного цикла:

  • подготовить-пакет
  • пакет
  • Предварительная интеграция-тест
  • интеграция-тест
  • пост-интегрально-тест
  • проверить
  • установка
  • развертывание
0 голосов
/ 26 ноября 2010

Оформить API-интерфейс maven-монитора

Вы можете добавить EventMonitor к диспетчеру, а затем перехватить КОНЕЦ события 'processor-execute': оно отправляется после того, как все завершено, т. Е. Даже после того, как вы видите вывод 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()
{
    ...
}
0 голосов
/ 25 сентября 2008

Обычно это вопрос конфигурации. Возможно, вам придется настроить проект только для mojo и сделать его зависимым от всех других проектов. Или вы можете заставить один из дочерних проектов быть последним, сделав его зависимым от всех других детей.

...