The API for plugins - Mojos - development
—
Essential interfaces and base classes for creating Maven plugins. Provides the fundamental Mojo contract and ready-to-use AbstractMojo base class with logging and context support.
The main contract required for all Maven plugins to interact with the Maven infrastructure. Every plugin must implement this interface to define its execution behavior and integrate with Maven's logging system.
/**
* Main contract for Maven plugins (Mojos) to interact with Maven infrastructure
*/
public interface Mojo {
/** The component role hint for Plexus container */
String ROLE = Mojo.class.getName();
/**
* Perform whatever build-process behavior this Mojo implements.
* Main trigger for the Mojo inside the Maven system.
*
* @throws MojoExecutionException if an unexpected problem occurs (BUILD ERROR)
* @throws MojoFailureException if an expected problem occurs (BUILD FAILURE)
*/
void execute() throws MojoExecutionException, MojoFailureException;
/**
* Inject a standard Maven logging mechanism
* @param log a new logger
*/
void setLog(Log log);
/**
* Get access to the Maven logging mechanism
* @return logger for creating messages at debug, info, warn, and error levels
*/
Log getLog();
}Abstract base class that provides most infrastructure required to implement a Mojo except for the execute method. Includes built-in logging management with fallback to SystemStreamLog and plugin context support.
/**
* Abstract class providing Mojo infrastructure except for execute method.
* Use @Mojo annotation with goal name:
* @Mojo(name = "<goal-name>")
*/
public abstract class AbstractMojo implements Mojo, ContextEnabled {
/**
* Set the logger for this Mojo
* @param log the logger instance
*/
public void setLog(Log log);
/**
* Get the logger, creating SystemStreamLog if none injected
* @return logger instance, never null
*/
public Log getLog();
/**
* Get the plugin container context
* @return Map containing shared context data
*/
public Map getPluginContext();
/**
* Set the plugin container context
* @param pluginContext Map of shared context data
*/
public void setPluginContext(Map pluginContext);
}Usage Example:
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
/**
* Example plugin demonstrating AbstractMojo usage
* @goal process-files
* @phase process-sources
*/
public class ProcessFilesMojo extends AbstractMojo {
/**
* Directory to process
* @parameter property="processDir" default-value="${project.basedir}/src/main/resources"
*/
private File processDirectory;
/**
* Skip processing
* @parameter property="skip" default-value="false"
*/
private boolean skip;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (skip) {
getLog().info("Skipping file processing");
return;
}
getLog().info("Processing files in: " + processDirectory);
if (!processDirectory.exists()) {
throw new MojoFailureException("Process directory does not exist: " + processDirectory);
}
try {
// Your plugin logic here
processFiles(processDirectory);
getLog().info("File processing completed successfully");
} catch (IOException e) {
throw new MojoExecutionException("Failed to process files", e);
}
}
private void processFiles(File directory) throws IOException {
getLog().debug("Starting file processing in " + directory);
// Implementation details...
}
}Interface allowing Mojos to communicate with each other by sharing data through the plugin container context. The plugin manager populates the context before executing Mojos.
/**
* Enables Mojos to share data with other Mojos beyond project's source root and attachments
*/
public interface ContextEnabled {
/**
* Set a new shared context Map to a mojo before executing it
* @param pluginContext a new Map for sharing data
*/
void setPluginContext(Map pluginContext);
/**
* Get the Map stored in the plugin container's context
* @return Map containing shared context data
*/
Map getPluginContext();
}Usage Example:
public class DataProducerMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException {
// Store data for other mojos
getPluginContext().put("processedData", someProcessedData);
getPluginContext().put("timestamp", System.currentTimeMillis());
}
}
public class DataConsumerMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException {
// Retrieve data from other mojos
Object data = getPluginContext().get("processedData");
Long timestamp = (Long) getPluginContext().get("timestamp");
if (data != null) {
getLog().info("Using data from previous mojo, created at: " + new Date(timestamp));
}
}
}When extending AbstractMojo, use these key annotations to configure your plugin:
@Mojo(
name = "goal-name", // Required: Goal name users will invoke
defaultPhase = LifecyclePhase.COMPILE, // Optional: Default lifecycle phase
requiresDependencyResolution = ResolutionScope.COMPILE, // Optional: Dependency scope needed
threadSafe = true // Optional: Can run in parallel builds
)/**
* @parameter property="propertyName" default-value="defaultValue"
* @required
*/
private String configValue;/**
* @component
*/
private SomeComponent injectedComponent;Install with Tessl CLI
npx tessl i tessl/maven-org-apache-maven--maven-plugin-api