CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-maven--maven-core

Maven Core classes - the core engine of Apache Maven build system

Pending
Overview
Eval results
Files

lifecycle-management.mddocs/

Lifecycle Management

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.

Core Lifecycle Execution

LifecycleExecutor Interface

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() + "]");
        }
    }
}

Execution Plans

MavenExecutionPlan Class

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());
    }
}

Lifecycle Definitions

Lifecycle Class

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);
}

DefaultLifecycles Class

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

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");
            }
        }
    }
}

Custom Lifecycle Participants

AbstractMavenLifecycleParticipant

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());
        }
    }
}

Types

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

docs

core-execution.md

exception-handling.md

index.md

lifecycle-management.md

plugin-system.md

project-management.md

repository-system.md

tile.json