The API for plugins - Mojos - development
—
Metadata classes for describing plugins, mojos, and their parameters. Used by Maven tools, IDEs, and the runtime to understand plugin structure and configuration options.
Describes a complete plugin with all its mojos and metadata. Contains plugin coordinates, goal prefix, and collection of MojoDescriptors.
/**
* Describes a complete Maven plugin with all its mojos and metadata
*/
public class PluginDescriptor extends ComponentSetDescriptor implements Cloneable {
/**
* Get the plugin's group ID
* @return Maven group ID (e.g., "org.apache.maven.plugins")
*/
public String getGroupId();
/**
* Set the plugin's group ID
* @param groupId Maven group ID
*/
public void setGroupId(String groupId);
/**
* Get the plugin's artifact ID
* @return Maven artifact ID (e.g., "maven-compiler-plugin")
*/
public String getArtifactId();
/**
* Set the plugin's artifact ID
* @param artifactId Maven artifact ID
*/
public void setArtifactId(String artifactId);
/**
* Get the plugin's version
* @return plugin version string
*/
public String getVersion();
/**
* Set the plugin's version
* @param version plugin version string
*/
public void setVersion(String version);
/**
* Get the plugin's goal prefix
* @return goal prefix used to invoke plugin goals (e.g., "compiler")
*/
public String getGoalPrefix();
/**
* Set the plugin's goal prefix
* @param goalPrefix goal prefix for invoking goals
*/
public void setGoalPrefix(String goalPrefix);
/**
* Get all mojos in this plugin
* @return List of MojoDescriptor objects
*/
public List<MojoDescriptor> getMojos();
/**
* Set the list of mojos for this plugin
* @param mojos List of MojoDescriptor objects
*/
public void setMojos(List<MojoDescriptor> mojos);
/**
* Find a specific mojo by goal name
* @param goal the goal name to search for
* @return MojoDescriptor for the goal, or null if not found
*/
public MojoDescriptor getMojo(String goal);
/**
* Add a mojo to this plugin
* @param mojoDescriptor the mojo descriptor to add
* @throws DuplicateMojoDescriptorException if goal already exists
*/
public void addMojo(MojoDescriptor mojoDescriptor) throws DuplicateMojoDescriptorException;
/**
* Create plugin key from coordinates
* @param groupId plugin group ID
* @param artifactId plugin artifact ID
* @param version plugin version
* @return plugin key string in format "groupId:artifactId:version"
*/
public static String constructPluginKey(String groupId, String artifactId, String version);
/**
* Get plugin key for this descriptor
* @return plugin key string
*/
public String getPluginLookupKey();
/**
* Get plugin identifier with version
* @return identifier string in format "groupId:artifactId:version"
*/
public String getId();
/**
* Get the plugin name
* @return human-readable plugin name
*/
public String getName();
/**
* Set the plugin name
* @param name human-readable plugin name
*/
public void setName(String name);
/**
* Get the plugin description
* @return description text
*/
public String getDescription();
/**
* Set the plugin description
* @param description description text
*/
public void setDescription(String description);
/**
* Get the plugin source location
* @return source file or URL
*/
public String getSource();
/**
* Set the plugin source location
* @param source source file or URL
*/
public void setSource(String source);
/**
* Check if plugin is inherited by default in child projects
* @return true if inherited by default
*/
public boolean isInheritedByDefault();
/**
* Set whether plugin is inherited by default in child projects
* @param inheritedByDefault true if inherited by default
*/
public void setInheritedByDefault(boolean inheritedByDefault);
/**
* Get default plugin artifact ID from goal prefix
* @param id goal prefix
* @return artifact ID in format "maven-{id}-plugin"
*/
public static String getDefaultPluginArtifactId(String id);
/**
* Get default plugin group ID
* @return "org.apache.maven.plugins"
*/
public static String getDefaultPluginGroupId();
/**
* Extract goal prefix from artifact ID
* @param artifactId plugin artifact ID
* @return extracted goal prefix
*/
public static String getGoalPrefixFromArtifactId(String artifactId);
}Usage Example:
// Reading plugin descriptor from plugin.xml
PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
try (FileReader reader = new FileReader("plugin.xml")) {
PluginDescriptor descriptor = builder.build(reader);
System.out.println("Plugin: " + descriptor.getId());
System.out.println("Goal prefix: " + descriptor.getGoalPrefix());
for (MojoDescriptor mojo : descriptor.getMojos()) {
System.out.println(" Goal: " + mojo.getGoal());
System.out.println(" Phase: " + mojo.getPhase());
}
}Describes individual Mojo metadata and configuration including goal name, execution phase, parameters, and behavioral flags.
/**
* Describes individual Mojo metadata and configuration
*/
public class MojoDescriptor extends ComponentDescriptor<Mojo> implements Cloneable {
/** Execution strategy constant: "once-per-session" */
public static final String SINGLE_PASS_EXEC_STRATEGY = "once-per-session";
/** Execution strategy constant: "always" */
public static final String MULTI_PASS_EXEC_STRATEGY = "always";
/**
* Get the goal name for this mojo
* @return goal name (e.g., "compile", "test")
*/
public String getGoal();
/**
* Set the goal name for this mojo
* @param goal goal name
*/
public void setGoal(String goal);
/**
* Get the default lifecycle phase for this mojo
* @return lifecycle phase name (e.g., "compile", "test")
*/
public String getPhase();
/**
* Set the default lifecycle phase for this mojo
* @param phase lifecycle phase name
*/
public void setPhase(String phase);
/**
* Get phase to execute before this mojo
* @return phase name to execute first
*/
public String getExecutePhase();
/**
* Set phase to execute before this mojo
* @param executePhase phase name to execute first
*/
public void setExecutePhase(String executePhase);
/**
* Get goal to execute before this mojo
* @return goal name to execute first
*/
public String getExecuteGoal();
/**
* Set goal to execute before this mojo
* @param executeGoal goal name to execute first
*/
public void setExecuteGoal(String executeGoal);
/**
* Get lifecycle to execute
* @return lifecycle identifier
*/
public String getExecuteLifecycle();
/**
* Set lifecycle to execute
* @param executeLifecycle lifecycle identifier
*/
public void setExecuteLifecycle(String executeLifecycle);
/**
* Get all parameters for this mojo
* @return List of Parameter objects
*/
public List<Parameter> getParameters();
/**
* Set the parameters for this mojo
* @param parameters List of Parameter objects
*/
public void setParameters(List<Parameter> parameters);
/**
* Get parameters as a name-keyed map
* @return Map of parameter name to Parameter object
*/
public Map<String, Parameter> getParameterMap();
/**
* Add a parameter to this mojo
* @param parameter Parameter to add
* @throws DuplicateParameterException if parameter name already exists
*/
public void addParameter(Parameter parameter) throws DuplicateParameterException;
/**
* Check if this mojo is an aggregator
* @return true if mojo aggregates across all projects
*/
public boolean isAggregator();
/**
* Set whether this mojo is an aggregator
* @param aggregator true if mojo should aggregate across projects
*/
public void setAggregator(boolean aggregator);
/**
* Check if this mojo is thread-safe
* @return true if mojo can run in parallel builds
*/
public boolean isThreadSafe();
/**
* Set whether this mojo is thread-safe
* @param threadSafe true if mojo can run in parallel
*/
public void setThreadSafe(boolean threadSafe);
/**
* Check if inherited by default in sub-projects
* @return true if inherited by default
*/
public boolean isInheritedByDefault();
/**
* Set whether inherited by default in sub-projects
* @param inheritedByDefault true if inherited by default
*/
public void setInheritedByDefault(boolean inheritedByDefault);
/**
* Check if this mojo supports direct invocation only
* @return true if can only be invoked directly (not bound to lifecycle)
*/
public boolean isDirectInvocationOnly();
/**
* Set whether this mojo supports direct invocation only
* @param directInvocationOnly true if direct invocation only
*/
public void setDirectInvocationOnly(boolean directInvocationOnly);
/**
* Get dependency resolution requirement
* @return dependency resolution scope required
*/
public String getDependencyResolutionRequired();
/**
* Set dependency resolution requirement
* @param requiresDependencyResolution dependency resolution scope
*/
public void setDependencyResolutionRequired(String requiresDependencyResolution);
/**
* Get dependency collection requirement
* @return dependency collection scope required
* @since 3.0-alpha-3
*/
public String getDependencyCollectionRequired();
/**
* Set dependency collection requirement
* @param requiresDependencyCollection dependency collection scope
* @since 3.0-alpha-3
*/
public void setDependencyCollectionRequired(String requiresDependencyCollection);
/**
* Get the execution strategy
* @return execution strategy (SINGLE_PASS_EXEC_STRATEGY or MULTI_PASS_EXEC_STRATEGY)
*/
public String getExecutionStrategy();
/**
* Set the execution strategy
* @param executionStrategy execution strategy
*/
public void setExecutionStrategy(String executionStrategy);
/**
* Get the mojo language
* @return language (e.g., "java")
*/
public String getLanguage();
/**
* Set the mojo language
* @param language language (e.g., "java")
*/
public void setLanguage(String language);
/**
* Check if reports are required
* @return true if reports are required
*/
public boolean isRequiresReports();
/**
* Set whether reports are required
* @param requiresReports true if reports are required
*/
public void setRequiresReports(boolean requiresReports);
/**
* Get project requirement
* @return true if project object is required
*/
public boolean isProjectRequired();
/**
* Set project requirement
* @param requiresProject true if project object is required
*/
public void setProjectRequired(boolean requiresProject);
/**
* Get online requirement
* @return true if network access is required
*/
public boolean isOnlineRequired();
/**
* Set online requirement
* @param requiresOnline true if network access is required
*/
public void setOnlineRequired(boolean requiresOnline);
/**
* Get the version since this mojo was added
* @return version string
*/
public String getSince();
/**
* Set the version since this mojo was added
* @param since version string
*/
public void setSince(String since);
/**
* Get deprecation message
* @return deprecation message or null if not deprecated
*/
public String getDeprecated();
/**
* Set deprecation message
* @param deprecated deprecation message
*/
public void setDeprecated(String deprecated);
/**
* Get mojo description
* @return description text
*/
public String getDescription();
/**
* Set mojo description
* @param description description text
*/
public void setDescription(String description);
}Describes individual mojo parameters including name, type, requirements, and default values.
/**
* Describes individual mojo parameters
*/
public class Parameter implements Cloneable {
/**
* Get parameter name
* @return parameter name used in configuration
*/
public String getName();
/**
* Set parameter name
* @param name parameter name
*/
public void setName(String name);
/**
* Get parameter alias
* @return alternative name for this parameter
*/
public String getAlias();
/**
* Set parameter alias
* @param alias alternative name for this parameter
*/
public void setAlias(String alias);
/**
* Get parameter type
* @return Java type name (e.g., "java.lang.String", "java.io.File")
*/
public String getType();
/**
* Set parameter type
* @param type Java type name
*/
public void setType(String type);
/**
* Check if parameter is required
* @return true if parameter must be provided
*/
public boolean isRequired();
/**
* Set whether parameter is required
* @param required true if parameter must be provided
*/
public void setRequired(boolean required);
/**
* Check if parameter is editable
* @return true if parameter can be configured by users
*/
public boolean isEditable();
/**
* Set whether parameter is editable
* @param editable true if parameter can be configured
*/
public void setEditable(boolean editable);
/**
* Get parameter description
* @return description text for documentation
*/
public String getDescription();
/**
* Set parameter description
* @param description description text
*/
public void setDescription(String description);
/**
* Get expression for property-based injection
* @return expression string (e.g., "${project.build.directory}")
*/
public String getExpression();
/**
* Set expression for property-based injection
* @param expression expression string
*/
public void setExpression(String expression);
/**
* Get default value
* @return default value as string
*/
public String getDefaultValue();
/**
* Set default value
* @param defaultValue default value as string
*/
public void setDefaultValue(String defaultValue);
/**
* Get implementation hint for dependency injection
* @return implementation class name
*/
public String getImplementation();
/**
* Set implementation hint for dependency injection
* @param implementation implementation class name
*/
public void setImplementation(String implementation);
/**
* Get component requirement
* @return Requirement object for dependency injection
*/
public Requirement getRequirement();
/**
* Set component requirement
* @param requirement Requirement object for dependency injection
*/
public void setRequirement(Requirement requirement);
/**
* Get since version
* @return version when parameter was added
*/
public String getSince();
/**
* Set since version
* @param since version when parameter was added
*/
public void setSince(String since);
/**
* Get deprecation message
* @return deprecation message or null if not deprecated
*/
public String getDeprecated();
/**
* Set deprecation message
* @param deprecated deprecation message
*/
public void setDeprecated(String deprecated);
/**
* Create a shallow copy of this parameter
* @return cloned Parameter instance
*/
public Parameter clone();
}Describes component requirements/dependencies for dependency injection. This is an immutable class initialized through constructors.
/**
* Describes component requirements for dependency injection (immutable)
*/
public class Requirement implements Cloneable {
/**
* Create requirement with role only
* @param role fully-qualified interface or class name
*/
public Requirement(String role);
/**
* Create requirement with role and hint
* @param role fully-qualified interface or class name
* @param roleHint role hint for distinguishing implementations
*/
public Requirement(String role, String roleHint);
/**
* Get component role
* @return fully-qualified interface or class name
*/
public String getRole();
/**
* Get role hint for distinguishing implementations
* @return role hint string or null if not specified
*/
public String getRoleHint();
/**
* Create a shallow copy of this requirement
* @return cloned Requirement instance
*/
public Requirement clone();
}Builds PluginDescriptor objects from plugin.xml files, converting XML metadata into Java objects.
/**
* Builds PluginDescriptor objects from plugin.xml files
*/
public class PluginDescriptorBuilder {
/**
* Build PluginDescriptor from plugin.xml reader
* @param reader Reader for plugin.xml content
* @return PluginDescriptor object
* @throws PlexusConfigurationException if XML is invalid
*/
public PluginDescriptor build(Reader reader) throws PlexusConfigurationException;
/**
* Build PluginDescriptor from plugin.xml reader with source tracking
* @param reader Reader for plugin.xml content
* @param source source identifier for error reporting
* @return PluginDescriptor object
* @throws PlexusConfigurationException if XML is invalid
*/
public PluginDescriptor build(Reader reader, String source) throws PlexusConfigurationException;
}Usage Example:
// Build descriptor from plugin.xml
PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
try (FileReader reader = new FileReader("src/main/resources/META-INF/maven/plugin.xml")) {
PluginDescriptor descriptor = builder.build(reader, "plugin.xml");
// Access plugin metadata
System.out.println("Plugin: " + descriptor.getArtifactId());
System.out.println("Version: " + descriptor.getVersion());
System.out.println("Goals:");
for (MojoDescriptor mojo : descriptor.getMojos()) {
System.out.println(" " + mojo.getGoal() + " (phase: " + mojo.getPhase() + ")");
for (Parameter param : mojo.getParameters()) {
System.out.println(" Parameter: " + param.getName() +
" (" + param.getType() + ")" +
(param.isRequired() ? " [required]" : ""));
}
}
}Exception classes for handling errors during descriptor parsing and validation.
Base exception for plugin descriptor problems.
/**
* Base exception for plugin descriptor problems
*/
public class InvalidPluginDescriptorException extends PlexusConfigurationException {
public InvalidPluginDescriptorException(String message);
public InvalidPluginDescriptorException(String message, Throwable cause);
}Thrown when duplicate mojo goals are found in a plugin.
/**
* Exception for duplicate mojo goals in a plugin
*/
public class DuplicateMojoDescriptorException extends InvalidPluginDescriptorException {
public DuplicateMojoDescriptorException(String goalName);
}Thrown when duplicate parameter names are found in a mojo.
/**
* Exception for duplicate parameter names in a mojo
*/
public class DuplicateParameterException extends InvalidPluginDescriptorException {
public DuplicateParameterException(String parameterName);
}Thrown when invalid parameter definitions are encountered.
/**
* Exception for invalid parameter definitions
*/
public class InvalidParameterException extends InvalidPluginDescriptorException {
public InvalidParameterException(String message, Throwable cause);
}PluginDescriptor plugin = new PluginDescriptor();
plugin.setGroupId("com.example");
plugin.setArtifactId("my-maven-plugin");
plugin.setVersion("1.0.0");
plugin.setGoalPrefix("example");
MojoDescriptor mojo = new MojoDescriptor();
mojo.setGoal("process");
mojo.setPhase("compile");
mojo.setImplementation("com.example.ProcessMojo");
Parameter param = new Parameter();
param.setName("inputDir");
param.setType("java.io.File");
param.setRequired(true);
param.setExpression("${project.build.sourceDirectory}");
param.setDescription("Input directory to process");
mojo.addParameter(param);
plugin.addMojo(mojo);// Parse plugin.xml from classpath
InputStream stream = getClass().getResourceAsStream("/META-INF/maven/plugin.xml");
PluginDescriptor descriptor = new PluginDescriptorBuilder()
.build(new InputStreamReader(stream), "plugin.xml");
// Find specific mojo
MojoDescriptor processMojo = descriptor.getMojo("process");
if (processMojo != null) {
System.out.println("Process mojo found in phase: " + processMojo.getPhase());
// Check parameters
Map<String, Parameter> params = processMojo.getParameterMap();
if (params.containsKey("inputDir")) {
Parameter inputDir = params.get("inputDir");
System.out.println("Input dir type: " + inputDir.getType());
System.out.println("Input dir required: " + inputDir.isRequired());
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-maven--maven-plugin-api