Maven Core classes - the core engine of Apache Maven build system
—
Maven Core lifecycle management provides APIs for orchestrating build lifecycles, managing execution plans, and coordinating the execution of build phases and goals. The lifecycle system is responsible for determining which plugins and goals to execute and in what order.
Primary interface for lifecycle execution and planning.
public interface LifecycleExecutor {
/**
* Calculate execution plan for specified tasks and projects.
*
* @param session Maven session containing projects and configuration
* @param tasks array of tasks (phases/goals) to execute
* @return execution plan containing ordered mojo executions
* @throws PluginNotFoundException if required plugin cannot be found
* @throws PluginResolutionException if plugin resolution fails
* @throws LifecyclePhaseNotFoundException if phase is not defined
* @throws LifecycleNotFoundException if lifecycle is not found
* @throws InvalidPluginDescriptorException if plugin descriptor is invalid
*/
MavenExecutionPlan calculateExecutionPlan(MavenSession session, String... tasks)
throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
LifecycleNotFoundException, InvalidPluginDescriptorException;
/**
* Calculate execution plan for specific projects.
*
* @param session Maven session
* @param projects list of projects to plan for
* @param tasks array of tasks to execute
* @return execution plan
*/
MavenExecutionPlan calculateExecutionPlan(MavenSession session, List<MavenProject> projects, String... tasks)
throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
LifecycleNotFoundException, InvalidPluginDescriptorException;
/**
* Execute the Maven session.
*
* @param session Maven session to execute
*/
void execute(MavenSession session);
/**
* Execute forked executions for a mojo.
*
* @param mojoExecution mojo execution that requires forked executions
* @param session Maven session
* @return list of projects from forked executions
* @throws LifecycleExecutionException if execution fails
*/
List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)
throws LifecycleExecutionException;
}Lifecycle Execution Example:
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.lifecycle.MavenExecutionPlan;
@Component
private LifecycleExecutor lifecycleExecutor;
public void executeLifecyclePhases(MavenSession session) throws Exception {
// Calculate execution plan for compile phase
MavenExecutionPlan plan = lifecycleExecutor.calculateExecutionPlan(
session, "clean", "compile", "test");
System.out.println("Execution plan contains " + plan.size() + " mojo executions:");
for (MojoExecution execution : plan.getMojoExecutions()) {
System.out.println(" " + execution.getLifecyclePhase() + ": " +
execution.getPlugin().getArtifactId() + ":" + execution.getGoal());
}
// Execute the session (this will execute the calculated plan)
lifecycleExecutor.execute(session);
}
public void analyzeExecutionPlan(MavenSession session, String... goals) throws Exception {
MavenExecutionPlan plan = lifecycleExecutor.calculateExecutionPlan(session, goals);
// Group executions by lifecycle phase
Map<String, List<MojoExecution>> executionsByPhase = new LinkedHashMap<>();
for (MojoExecution execution : plan) {
String phase = execution.getLifecyclePhase();
executionsByPhase.computeIfAbsent(phase, k -> new ArrayList<>()).add(execution);
}
// Display execution plan by phase
System.out.println("Execution Plan Analysis:");
for (Map.Entry<String, List<MojoExecution>> entry : executionsByPhase.entrySet()) {
System.out.println("Phase: " + entry.getKey());
for (MojoExecution execution : entry.getValue()) {
Plugin plugin = execution.getPlugin();
System.out.println(" -> " + plugin.getGroupId() + ":" +
plugin.getArtifactId() + ":" + execution.getGoal() +
" [" + execution.getExecutionId() + "]");
}
}
}Represents an ordered sequence of mojo executions for a build.
public class MavenExecutionPlan implements Iterable<MojoExecution> {
/**
* Get all mojo executions in the plan.
*
* @return list of mojo executions in execution order
*/
public List<MojoExecution> getMojoExecutions();
/**
* Get iterator over mojo executions.
*
* @return iterator for executions
*/
public Iterator<MojoExecution> iterator();
/**
* Get number of executions in the plan.
*
* @return number of mojo executions
*/
public int size();
/**
* Check if plan is empty.
*
* @return true if no executions in plan
*/
public boolean isEmpty();
/**
* Find mojo executions by plugin key.
*
* @param pluginKey plugin key (groupId:artifactId)
* @return list of matching executions
*/
public List<MojoExecution> getMojoExecutions(String pluginKey);
/**
* Get last mojo execution for a plugin.
*
* @param pluginKey plugin key
* @return last execution or null if not found
*/
public MojoExecution findLastInPhase(String pluginKey);
}Execution Plan Usage:
public void processExecutionPlan(MavenExecutionPlan plan) {
System.out.println("Processing execution plan with " + plan.size() + " executions");
// Iterate through all executions
for (MojoExecution execution : plan) {
Plugin plugin = execution.getPlugin();
System.out.println("Will execute: " + plugin.getArtifactId() +
":" + execution.getGoal() +
" in phase: " + execution.getLifecyclePhase());
}
// Find specific plugin executions
List<MojoExecution> compilerExecutions = plan.getMojoExecutions("org.apache.maven.plugins:maven-compiler-plugin");
if (!compilerExecutions.isEmpty()) {
System.out.println("Found " + compilerExecutions.size() + " compiler plugin executions:");
for (MojoExecution execution : compilerExecutions) {
System.out.println(" " + execution.getGoal() + " [" + execution.getExecutionId() + "]");
}
}
// Check for test execution
MojoExecution lastSurefireExecution = plan.findLastInPhase("org.apache.maven.plugins:maven-surefire-plugin");
if (lastSurefireExecution != null) {
System.out.println("Tests will be executed by: " + lastSurefireExecution.getExecutionId());
}
}Represents a complete lifecycle definition with phases and default bindings.
public class Lifecycle {
/**
* Get lifecycle identifier.
*
* @return lifecycle ID (e.g., "default", "clean", "site")
*/
public String getId();
/**
* Set lifecycle identifier.
*
* @param id lifecycle ID
*/
public void setId(String id);
/**
* Get ordered list of phases in this lifecycle.
*
* @return list of phase names in execution order
*/
public List<String> getPhases();
/**
* Set phases for this lifecycle.
*
* @param phases ordered list of phase names
*/
public void setPhases(List<String> phases);
/**
* Get default phase bindings for packaging types.
*
* @return map from packaging type to phase bindings
*/
public Map<String, LifecyclePhase> getDefaultPhases();
/**
* Set default phase bindings.
*
* @param defaultPhases map of packaging-specific bindings
*/
public void setDefaultPhases(Map<String, LifecyclePhase> defaultPhases);
/**
* Get default bindings for a specific packaging type.
*
* @param packaging packaging type (e.g., "jar", "war", "pom")
* @return phase bindings for the packaging type
*/
public Map<String, String> getDefaultGoals(String packaging);
}Container for standard Maven lifecycles.
public class DefaultLifecycles {
/**
* Get all standard lifecycles.
*
* @return list of default lifecycles (default, clean, site)
*/
public List<Lifecycle> getLifeCycles();
/**
* Get lifecycle by ID.
*
* @param lifecycleId lifecycle identifier
* @return lifecycle instance or null if not found
*/
public Lifecycle get(String lifecycleId);
/**
* Get phases for a specific lifecycle.
*
* @param lifecycleId lifecycle identifier
* @return ordered list of phase names
*/
public List<String> getLifecyclePhases(String lifecycleId);
}Lifecycle Definition Example:
import org.apache.maven.lifecycle.Lifecycle;
import org.apache.maven.lifecycle.DefaultLifecycles;
@Component
private DefaultLifecycles defaultLifecycles;
public void inspectLifecycles() {
// Get all standard lifecycles
List<Lifecycle> lifecycles = defaultLifecycles.getLifeCycles();
for (Lifecycle lifecycle : lifecycles) {
System.out.println("Lifecycle: " + lifecycle.getId());
System.out.println("Phases: " + lifecycle.getPhases());
// Show default bindings for common packaging types
String[] packagingTypes = {"jar", "war", "pom", "maven-plugin"};
for (String packaging : packagingTypes) {
Map<String, String> bindings = lifecycle.getDefaultGoals(packaging);
if (!bindings.isEmpty()) {
System.out.println(" Default bindings for " + packaging + ":");
for (Map.Entry<String, String> binding : bindings.entrySet()) {
System.out.println(" " + binding.getKey() + " -> " + binding.getValue());
}
}
}
}
}
public void analyzeDefaultLifecycle() {
Lifecycle defaultLifecycle = defaultLifecycles.get("default");
if (defaultLifecycle != null) {
System.out.println("Default lifecycle phases:");
List<String> phases = defaultLifecycle.getPhases();
for (int i = 0; i < phases.size(); i++) {
System.out.println((i + 1) + ". " + phases.get(i));
}
// Show JAR packaging bindings
Map<String, String> jarBindings = defaultLifecycle.getDefaultGoals("jar");
System.out.println("\nDefault JAR packaging bindings:");
for (Map.Entry<String, String> entry : jarBindings.entrySet()) {
System.out.println(" " + entry.getKey() + " -> " + entry.getValue());
}
}
}Forked executions allow mojos to trigger separate lifecycle executions, typically used for pre-integration testing or parallel builds.
public interface LifecycleExecutor {
/**
* Execute forked executions for a mojo that requires them.
*
* @param mojoExecution the mojo execution requesting forked executions
* @param session Maven session
* @return list of projects resulting from forked executions
* @throws LifecycleExecutionException if forked execution fails
*/
List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)
throws LifecycleExecutionException;
}Forked Execution Example:
public void handleForkedExecution(MojoExecution mojoExecution, MavenSession session) throws Exception {
// Check if mojo has forked executions defined
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
if (mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null) {
System.out.println("Mojo " + mojoExecution.getGoal() + " requires forked execution");
// Execute forked executions
List<MavenProject> forkedProjects = lifecycleExecutor.executeForkedExecutions(
mojoExecution, session);
System.out.println("Forked execution completed for " + forkedProjects.size() + " projects:");
for (MavenProject project : forkedProjects) {
System.out.println(" " + project.getGroupId() + ":" + project.getArtifactId());
}
}
}
// Example: Integration test with forked lifecycle
public void runIntegrationTestsWithForking(MavenSession session) throws Exception {
// Find failsafe plugin execution (commonly uses forked executions)
MavenExecutionPlan plan = lifecycleExecutor.calculateExecutionPlan(
session, "pre-integration-test", "integration-test", "post-integration-test");
for (MojoExecution execution : plan) {
Plugin plugin = execution.getPlugin();
if ("maven-failsafe-plugin".equals(plugin.getArtifactId()) &&
"integration-test".equals(execution.getGoal())) {
System.out.println("Running integration tests with forked lifecycle");
// This may trigger forked executions to prepare test environment
List<MavenProject> forkedProjects = lifecycleExecutor.executeForkedExecutions(
execution, session);
if (!forkedProjects.isEmpty()) {
System.out.println("Forked executions prepared " + forkedProjects.size() +
" projects for integration testing");
}
}
}
}Base class for creating custom lifecycle participants that can hook into the build process.
public abstract class AbstractMavenLifecycleParticipant {
/**
* Called before projects are built. Allows modification of projects
* and execution request before lifecycle execution begins.
*
* @param session Maven session
* @throws MavenExecutionException if participant processing fails
*/
public void afterProjectsRead(MavenSession session) throws MavenExecutionException {
// Default implementation does nothing
}
/**
* Called after session is started but before lifecycle execution.
*
* @param session Maven session
* @throws MavenExecutionException if participant processing fails
*/
public void afterSessionStart(MavenSession session) throws MavenExecutionException {
// Default implementation does nothing
}
/**
* Called after session ends, regardless of success or failure.
*
* @param session Maven session
* @throws MavenExecutionException if participant processing fails
*/
public void afterSessionEnd(MavenSession session) throws MavenExecutionException {
// Default implementation does nothing
}
}Custom Lifecycle Participant Example:
import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.MavenExecutionException;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.component.annotations.Component;
@Component(role = AbstractMavenLifecycleParticipant.class, hint = "custom-participant")
public class CustomLifecycleParticipant extends AbstractMavenLifecycleParticipant {
@Override
public void afterProjectsRead(MavenSession session) throws MavenExecutionException {
System.out.println("Custom lifecycle participant: projects read");
// Modify projects before build starts
for (MavenProject project : session.getProjects()) {
// Add custom properties
project.getProperties().setProperty("custom.build.timestamp",
String.valueOf(System.currentTimeMillis()));
// Modify build configuration if needed
if ("jar".equals(project.getPackaging())) {
System.out.println("Customizing JAR project: " + project.getArtifactId());
// Custom logic for JAR projects
}
}
}
@Override
public void afterSessionStart(MavenSession session) throws MavenExecutionException {
System.out.println("Custom lifecycle participant: session started");
// Log build information
System.out.println("Build started for " + session.getProjects().size() + " projects");
System.out.println("Goals: " + session.getRequest().getGoals());
// Validate build environment
validateBuildEnvironment(session);
}
@Override
public void afterSessionEnd(MavenSession session) throws MavenExecutionException {
System.out.println("Custom lifecycle participant: session ended");
// Cleanup or post-build processing
long buildTime = System.currentTimeMillis() - session.getRequest().getStartTime().getTime();
System.out.println("Total build time: " + buildTime + "ms");
// Generate custom reports or notifications
generateBuildReport(session);
}
private void validateBuildEnvironment(MavenSession session) throws MavenExecutionException {
// Custom validation logic
String javaVersion = System.getProperty("java.version");
if (javaVersion.startsWith("1.8")) {
throw new MavenExecutionException("Java 8 is not supported for this build",
(Throwable) null);
}
}
private void generateBuildReport(MavenSession session) {
// Custom reporting logic
System.out.println("=== Build Report ===");
for (MavenProject project : session.getProjects()) {
System.out.println("Project: " + project.getName() + " - " + project.getVersion());
}
}
}public interface LifecyclePhase {
List<Plugin> getPlugins();
void addPlugin(Plugin plugin);
String toString();
}
public class LifecyclePhaseNotFoundException extends Exception {
public LifecyclePhaseNotFoundException(String message);
public LifecyclePhaseNotFoundException(String message, Throwable cause);
}
public class LifecycleNotFoundException extends Exception {
public LifecycleNotFoundException(String message);
public LifecycleNotFoundException(String message, Throwable cause);
}
public class InvalidPluginDescriptorException extends Exception {
public InvalidPluginDescriptorException(String message);
public InvalidPluginDescriptorException(String message, Throwable cause);
}
public interface MojoDescriptor {
String getExecutePhase();
String getExecuteGoal();
String getExecuteLifecycle();
boolean requiresProject();
boolean requiresReports();
boolean aggregator();
boolean requiresDirectInvocation();
boolean requiresOnline();
boolean inheritedByDefault();
String getPhase();
String getSince();
String getDeprecated();
}
public interface LifecycleMapping {
Map<String, String> getPhases(String packaging);
List<String> getOptionalMojos(String packaging);
}
public interface LifecycleMappingDelegate {
Map<String, List<MojoExecution>> calculateLifecycleMappings(MavenSession session,
MavenProject project, Lifecycle lifecycle, String lifecyclePhase)
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
MojoNotFoundException, InvalidPluginDescriptorException;
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-maven--maven-core