Fix precedence of user property for collection parameters on mojo
According to the observed rules of Maven, if a plugin parameter is set in the POM (i.e., in the plugin configuration) and that parameter is mapped to a user property, the assignment in the POM should take precedence over the user property. Consider the case when the nodeVersion
parameter is defined in the POM as follows:
<configuration>
<nodeVersion>18</nodeVersion>
</configuration>
When the user runs mvn antora:antora -Dnode.version=20
, the value will be 18
, not 20
. Hence, the assignment in the plugin configuration takes precedence.
However, this precedence is not upheld when the parameter type is a collection (i.e., a list). Consider the case when the additionalOptions
parameter is defined in the POM as follows:
<configuration>
<additionalOptions>
<option>silent</option>
</additionalOptions>
</configuration>
When the user runs mvn antora:antora -Dantora.additionalOptions=clean
, the value resolves to a list with clean
instead of with silent
. Hence, the user property takes precedence.
I believe this behavior is the result of a bug in either Maven or Plexus. Here's what happens. When the parameter is not assigned, Maven sees the following resolved configuration:
<configuration>
<additionalOptions>${antora.additionalOptions}</additionalOptions>
</configuration>
(This can be found in the plugin.xml file in the packaged jar).
Notice that the value of the additionalOptions
element is an expression that references the user property. Since the user property is not defined, the expression resolves to null and hence an empty list is assigned to the field for the additionalOptions
parameter.
When the parameter is assigned in the POM, Maven sees the following resolved configuration:
<configuration>
<additionalOptions>
<option>silent</option>
</additionalOptions>
</configuration>
Everything looks correct. But there's a catch. The getValue()
method on the additionalOptions
element in the configuration object returns ${antora.additionalOptions}
. This leads Maven/Plexus to believe the element is empty at this stage. (The value should be null since the element has children). If the user property is defined, Maven will use the value of the user property, ignoring the children in the POM. That's how the user property is taking precedence over the parameter defined in the POM. If the user property is not defined, only then does Maven process the children.
This problem can be fixed using a ComponentConfigurator that extends the BasicComponentConfigurator. The configurator should set the value to null on any top-level element in the configuration that has children. That way, Maven will not consider the user property in those cases. In other words, the XML element for the parameter can't both have a value and children.