How do I program one Mojo to set another Mojo's configuration? For example: Mojo A requires configuration parameter A.foo
to be defined. A user can either specify A.foo
manually or run plugin B which will calculate the value for him/her.
Answering my own question:
It's possible to access a plugin's configuration or project-wide properties at runtime using a MavenProject
instance:
/**
* The maven project.
*
* @parameter expression="${project}"
* @readonly
*/
private MavenProject project;
You can then access a plugin's configuration at runtime:
private Plugin lookupPlugin(String key)
{
List plugins = getProject().getBuildPlugins();
for (Iterator iterator = plugins.iterator(); iterator.hasNext();)
{
Plugin plugin = (Plugin) iterator.next();
if(key.equalsIgnoreCase(plugin.getKey()))
return plugin;
}
return null;
}
...
Xpp3Dom configuration = (Xpp3Dom) Plugin.getConfiguration()
configuration.getChild("parameterName"); // get parameter
configuration.addChild(new Xpp3Dom("parameterName")); // add parameter
...
Note: Any configuration changes are discarded at the end of the current phase.
Source: Best way to access the runtime configuration of a maven plugin from a custom mojo?
Alternatively, you can get/set project-wide parameters using MavenProject.getProperties()
.
I guess the maven way would be to set a property in the first Mojo and to access it from the other Mojo.
This turns out to be a tricky thing to do mostly due to the timing of "configuration" of the plugins by the Maven runtime. Changing the "configuration" from getBuildPlugins is usually not going to work.
The best method is default-value if you are writing the target plugin, otherwise use properties.
With properties, but you have to be careful about how you use the properties. The caution is to realize that if your POM (or any parent) defines a value for a property, then the ${property} reference will be replaced when the POM is loaded. However if there is no "property" property then the ${property} reference stays and is only replaced with a null value at the last possible moment.
"default-value" is also evaluated at the last possible moment, and I think this is a safer solution because there is a logical reason why it must be evaluated at the last possible moment, where-as the non-existent property may just be an implementation detail that could change in future versions of Maven.
In my case I had to resort to properties because I wanted to control the "classesDirectory" of the surefire plugin. I wanted it to continue to default to ${project.build.outputDirectory} when Cobertura was not run, but when Cobertura was run I wanted it to use ${project.build.outputDirectory}/generated-classes/cobertura.
Define in your plugins section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<classesDirectory>${instrumentedClassesDirectory}</classesDirectory>
</configuration>
</plugin>
Then in the "source" plugin:
getProject().getProperties().put("instrumentedClassesDirectory", coberturaDir);
And make sure under no circumstances ever put anything like the following in any POM:
<properties>
<instrumentedClassesDirectory>${project.build.outputDirectory}</instrumentedClassesDirectory>
</properties>
because if you do, even though the value of the property is set by your source plugin, your destination plugin will not see the value. You can ignore this last caveat if your using a property passed into the default-value of the source plugin, but as said in my case that would not work because I did not want to change the value of project.build.outputDirectory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With