Java Maven Mojo: Complex Map Attribute
The example map attribute for a mojo mentioned at maven.apache.org is pretty straightforward as it defines a map with a string as the key and as the value below:
/**
* My Map.
*/
@Parameter
private Map myMap;
and the assigned config will look like this:
<myMap>
<key1>value1</key1>
<key2>value2</key2>
</myMap>
What I'm trying to achieve is a more advanced map that takes a string as a key and my own defined Person class as a value:
/**
* My Advanced Map.
*/
@Parameter
private Map<String,Person> myMap;
The Person class is in the same package as my MOJO and looks like this:
public class Person {
private String name;
private int age;
public void setName( String name )
{
this.name = name;
}
public void setAge( int age )
{
this.age = age;
}
public String getName( )
{
return this.name;
}
public int getAge( )
{
return this.age ;
}
}
I assume my MOJO config will look like this:
<myMap>
<firstPerson>
<person>
<name>steve</name>
<age>26</age>
</person>
</firstPerson>
<secondPerson>
<person>
<name>meruem</name>
<age>1</age>
</person>
</secondPerson>
</myMap>
Running this MOJO with the above config will create a map with specific keys, but I always get null values: {firstPerson = null, secondPerson = null}
Currently I don't know if I am doing anything wrong, or if this example is even supported, since no documentation was found that describes the "extended" attribute of the map, and my last case will now view the sources.
source to share
In fact, you are really close to a solution. You just need to configure your plugin this way (no inner element <person>
):
<myMap>
<firstPerson>
<name>steve</name>
<age>26</age>
</firstPerson>
<secondPerson>
<name>meruem</name>
<age>1</age>
</secondPerson>
</myMap>
To provide you with a complete working example, consider the following Maven plugin:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample.plugin</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0.0</version>
<packaging>maven-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
having the following MOJO declaring a target foo
and having a type parameter Map<String, Person>
that just writes the map as information:
@Mojo(name = "foo")
public class MyMojo extends AbstractMojo {
@Parameter
private Map<String, Person> map;
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info(map.toString());
}
}
and the next Person
class:
public class Person {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
Once this Maven plugin is installed in the repo (using mvn clean install
), we can use it in the project like this:
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>foo</id>
<phase>generate-sources</phase>
<goals>
<goal>foo</goal>
</goals>
<configuration>
<map>
<person1>
<name>Name 1</name>
<age>10</age>
</person1>
<person2>
<name>Name 2</name>
<age>20</age>
</person2>
</map>
</configuration>
</execution>
</executions>
</plugin>
Output of this plugin on startup mvn clean generate-sources
:
[INFO] --- test-maven-plugin:1.0.0:foo (add-source) @ test --- [INFO] {person1=Person [name=Name 1, age=10], person2=Person [name=Name 2, age=20]}
source to share