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)