简体   繁体   中英

Collecting data across multiple executions of Mojo in custom Maven plugin

I have a multi-module maven project , and I'd like to collect some information about all modules using a custom plugin .

I managed to get what I want for each module. Due to the nature of the information I collect, it would be much more effective to collect it in memory and dump the consolidated results at the very end .

Custom Mojo that illustrates the idea (and I know that does not work, see below):

@Mojo(name = "dummy")
public class DummyMojo extends AbstractMojo {

    private static Set<String> data = Collections.synchronizedSet(new HashSet<String>());

    @Parameter(defaultValue = "${project}", readonly = true)
    private MavenProject mavenProject;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        data.add(mavenProject.getArtifactId());
        getLog().info("Execution #" + data.size());
    }

}

This collects artifact IDs of all my modules (this is just an example to simplify, in reality I collect some other irrelevant stuff).

I'd like to dump the result at the very end of the build.

If I run this, I observe that 2 instances are created (I have >100 modules):

% mvn com.company:foo:1.0-SNAPSHOT:dummy | grep 'Execution #'
[INFO] Execution #1
...
[INFO] Execution #6
[INFO] Execution #13
[INFO] Execution #14
[INFO] Execution #15
[INFO] Execution #7
[INFO] Execution #8
[INFO] Execution #9
....
[INFO] Execution #90
[INFO] Execution #91
[INFO] Execution #13
[INFO] Execution #92
[INFO] Execution #14
[INFO] Execution #15
[INFO] Execution #39
[INFO] Execution #40
[INFO] Execution #41

So I observe that I cannot collect data for each module and share it across each Mojo execution using a static variable.

If I also print PID and ClassLoader , I observe that it all happens in the same JVM process, but a second classloader is used for some modules . I vaguely know why: the affected modules (legacy stuff) use an exotic plugin (NetBeans Maven plugin), and today I'm discovering that I have to add that disappointment to the heap of issues it caused us.

Anway, questions:

1) Is there a correct way to collect data in memory across all executions of a given Mojo during a single multimodule build? (Or is there a way to ensure all executions happen in same JVM & same class loader?)

2) How can I detect end of build, once all modules have been visited? I suppose there is something on the build I can observe... Sorry my understanding is incomplete there... Lifecycle, reactor... What concept am I missing to implement this?

I'm ready to read about how that is a Bad Idea! I'm just experimenting at this point: if I'm misguided I do need "reguidance".

I checked that Q/A but it was about sharing across 3 different Mojos for a single module.

(For now I can dump the results every time, the last one overwrites the previous result, it's OK for my use case, but if I can improve that, it would be great)

SonarQube does this in sonar-scanner-maven, see SonarQubeMojo .

0) Mojo has annotation aggregator = true

1) Data is collected in a static variable in the mojo

2) They determine "end of build" by counting visited modules and comparing that to expected total. If this is not last module then do nothing (or collect what needs collecting...), if it is then run the thing (consolidate results).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM