# What Is the Role of MavenSession in a Maven Build Lifecycle?

> Discover the role of MavenSession in a Maven build lifecycle. Learn how this central context object supplies plugins with essential environmental data throughout the build process.

- Repository: [The Apache Software Foundation/maven](https://github.com/apache/maven)
- Tags: internals
- Published: 2026-07-06

---

**MavenSession is the central execution context that represents a single invocation of Maven, holding the request configuration, reactor state, repository session, and build results while passing through every phase of the lifecycle to supply plugins with environmental data.**

In the Apache Maven source code, `MavenSession` serves as the single source of truth for everything that happens during a build. Understanding the role of MavenSession in a Maven build lifecycle is essential for developing custom plugins or extending the core reactor. This class, defined in [`impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java), acts as the bridge between the command-line invocation and the execution of individual Mojos.

## Core Responsibilities of MavenSession

### Holding the Execution Request

The session encapsulates the `MavenExecutionRequest` via the private field `request`, exposing command-line options, goals, and properties through methods like `getRequest()`, `getGoals()`, and `getUserProperties()`. This allows every component in the build to access the original intent of the invocation, including system properties and the list of modules to build.

### Tracking Build Results

Through the `result` field, the session maintains the `MavenExecutionResult`, recording success states and any collected exceptions accessible via `getResult()`. This ensures that failures in one module can be captured and reported without immediately terminating the entire reactor.

### Providing Repository System Access

The session supplies the `RepositorySystemSession` required by Aether for artifact resolution, available through `getRepositorySession()`. This connects the build to the local and remote repositories, enabling dependency downloads and metadata resolution.

### Managing the Reactor State

`MavenSession` maintains the complete list of projects in the reactor via `projects` and `allProjects`, tracking the thread-local current project and exposing it through `getCurrentProject()` and `getTopLevelProject()`. It also provides the `ProjectDependencyGraph` via `getProjectDependencyGraph()` for topological ordering of multi-module builds.

### Storing Plugin Contexts

The `pluginContextsByProjectAndPluginKey` map allows plugins to store state scoped to a specific project and plugin key, retrieved via `getPluginContext()`. This mechanism enables data persistence across different phases or repeated executions of the same plugin within a single session.

## How MavenSession Drives the Build Lifecycle

During the build lifecycle, Maven creates the session immediately after parsing the command line and validating the `MavenExecutionRequest`. As the reactor executes each module, the session travels through every phase, providing context to each Mojo. The session is typically injected into Mojos using the `${session}` expression, giving plugins access to the entire execution context.

## Accessing Build Context from a Mojo

Plugins obtain contextual data by injecting the session and calling its accessor methods:

```java
@Mojo(name = "show-info", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true)
public class ShowInfoMojo extends AbstractMojo {

    /** The current Maven session (injected by Maven). */
    @Parameter(defaultValue = "${session}", readonly = true)
    private MavenSession session;

    public void execute() throws MojoExecutionException {
        // Current project
        MavenProject project = session.getCurrentProject();

        // User-defined properties (-DmyProp=foo)
        String myProp = session.getUserProperties().getProperty("myProp");

        // Resolve the path of the local repository
        String localRepo = session.getLocalRepository().getBasedir().getAbsolutePath();

        getLog().info("Project: " + project.getArtifactId());
        getLog().info("myProp = " + myProp);
        getLog().info("Local repo = " + localRepo);
    }
}

```

*Key implementation details:* The methods `getCurrentProject()`, `getUserProperties()`, and `getLocalRepository()` are defined in [`MavenSession.java`](https://github.com/apache/maven/blob/main/MavenSession.java) and provide the core integration points for plugin development.

## Managing Plugin State Across Modules

The session enables stateful plugins to cache data across multiple module executions using the plugin context map:

```java
// Inside a mojo that runs multiple times for different modules
public void execute() throws MojoExecutionException {
    MavenProject project = session.getCurrentProject();

    // Obtain (or create) a map scoped to this project & plugin
    Map<String, Object> ctx = session.getPluginContext(this.getDescriptor(), project);

    // Store a value the first time the plugin runs
    ctx.computeIfAbsent("startTime", k -> Instant.now());

    Instant start = (Instant) ctx.get("startTime");
    getLog().info("Plugin started at " + start);
}

```

The `getPluginContext` method guarantees a non-null map that survives for the duration of the session, allowing plugins to avoid recalculating expensive data for each module.

## Navigating the Project Dependency Graph

Custom Mojos can access the reactor’s topological ordering through the session:

```java
ProjectDependencyGraph graph = session.getProjectDependencyGraph();
List<MavenProject> sorted = graph.getSortedProjects(); // topological order

```

This `ProjectDependencyGraph`, populated by Maven after the reactor is built, enables plugins to understand dependency relationships between modules and react to the overall build structure.

## Thread Safety and Parallel Builds

The `parallel` flag indicates whether the reactor may execute modules concurrently, exposed via `isParallel()` and `setParallel(boolean)`. For thread safety, Maven creates shallow clones of the session using the `clone()` method, ensuring each thread maintains its own "current project" via thread-local storage without corrupting the original session state. This design allows the session to act as a safe container for execution context even during highly parallel builds.

## Summary

- **Central execution context**: `MavenSession` represents a single Maven invocation from [`impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java), holding all environmental data from start to finish.
- **Request and results**: It encapsulates the `MavenExecutionRequest` and tracks the `MavenExecutionResult` through dedicated fields and accessor methods.
- **Repository and resolution**: It provides the `RepositorySystemSession` required for dependency resolution via `getRepositorySession()`.
- **Reactor management**: Maintains project lists, current project state via thread-local storage, and the dependency graph for multi-module builds.
- **Plugin integration**: Offers the `getPluginContext()` method for stateful plugin operations and accepts injection via the `${session}` expression.
- **Concurrency support**: Supports parallel builds through the `parallel` flag and safe cloning mechanisms that isolate per-thread state.

## Frequently Asked Questions

### What is the difference between MavenSession and MavenExecutionRequest?

`MavenExecutionRequest`, defined in [`api/maven-api/src/main/java/org/apache/maven/api/MavenExecutionRequest.java`](https://github.com/apache/maven/blob/main/api/maven-api/src/main/java/org/apache/maven/api/MavenExecutionRequest.java), captures the initial command-line configuration and user inputs before the build starts. `MavenSession` wraps that request and evolves throughout the lifecycle, accumulating results, repository sessions, and reactor state as the build progresses, making it the mutable container for execution context while the request remains the immutable snapshot of the original invocation.

### How does MavenSession support parallel builds?

The session tracks whether the reactor should run modules concurrently via the `parallel` boolean flag. When parallel execution is enabled, Maven creates shallow clones of the `MavenSession` using the `clone()` method so each thread maintains its own current project via thread-local storage without interfering with other threads. This ensures that the `getCurrentProject()` method returns the correct project for each concurrent execution branch.

### Can a plugin modify the MavenSession?

While plugins can read from the session and store data in plugin contexts via `getPluginContext()`, directly modifying core session attributes like the project list or execution request is not recommended and may lead to unpredictable build behavior. The session is intended to be the authoritative source of truth for the execution context, and modifications outside the intended extension points can break reactor consistency.

### Where is MavenSession instantiated in the Maven source code?

The session is instantiated in the Maven core after the `MavenExecutionRequest` is built and validated, specifically within the execution logic in [`impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java). It becomes the container for all subsequent build operations, including the reactor traversal and Mojo execution phases.