How do you force a maven MOJO to be executed only once at the end of a build?

前端 未结 7 1627
傲寒
傲寒 2021-02-08 13:06

I have a MOJO I would like executed once, and once only after the test phase of the last project in the reactor to run.

Using:

if (!getProject().isExecut         


        
相关标签:
7条回答
  • 2021-02-08 13:45

    Normally, this is a matter of configuration. You might have to setup a project just for the mojo and make it dependent on all of the other projects. Or you could force one of the child projects to be last by making it dependent on all of the other children.

    0 讨论(0)
  • 2021-02-08 13:48

    The best solution I have found for this is:

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

    This appears to work on the small build hierarchies I've tested with.

    0 讨论(0)
  • 2021-02-08 13:49

    Check out maven-monitor API

    You can add an EventMonitor to the dispatcher, and then trap the END of the 'reactor-execute' event: this is dispatched after everything is completed, i.e. even after you see the BUILD SUCCESSFUL/FAILED output.

    Here's how I used it recently to print a summary right at the end:

    /**
     * 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 讨论(0)
  • 2021-02-08 13:50

    There is a Sonatype blog entry that describes how to do this. The last project to be run will be the root project as it will contain module references to the rest. Thereforec you need a test in your mojo to check if the current project's directory is the same as the directory from where Maven was launched:

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

    In the referenced entry there is a pretty comprehensive example of how to use this in your mojo.

    0 讨论(0)
  • 2021-02-08 13:52

    The solution with using session.getEventDispatcher() no longer works since Maven 3.x. The whole eventing has been removed in this commit: https://github.com/apache/maven/commit/505423e666b9a8814e1c1aa5d50f4e73b8d710f4

    0 讨论(0)
  • 2021-02-08 13:57

    The best solution is relying on a lifecycle extension by extending your class from org.apache.maven.AbstractMavenLifecycleParticipant (see also https://maven.apache.org/examples/maven-3-lifecycle-extensions.html) which got a method afterSessionEnd added with https://issues.apache.org/jira/browse/MNG-5640 (fixed in Maven 3.2.2).

    0 讨论(0)
提交回复
热议问题