# Deep Dive into MavenSession for Advanced Users: Architecture, API, and Lifecycle

> Explore the MavenSession architecture, API, and lifecycle for advanced users. Understand how this central Maven façade manages thread-safe build state and core services.

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

---

**The MavenSession is the central façade in Apache Maven that provides thread-safe access to build-time state, repository configuration, and core services through a dependency-injection managed scope that spans the entire build lifecycle.**

The MavenSession serves as the primary integration point for plugins, extensions, and custom code within the Apache Maven build system. This deep dive explores the `org.apache.maven.api.Session` interface and its implementation, revealing how Maven aggregates artifact resolution, repository handling, and project state into a cohesive, thread-safe API. Understanding the Session's architecture is essential for advanced users who need to manipulate build contexts, implement custom resolution logic, or create derived sessions for isolated sub-builds.

## Understanding the MavenSession API

The public contract for MavenSession lives in `org.apache.maven.api.Session` within the `api/maven-api-core` module. This interface extends `ProtoSession` and is annotated with `@Experimental` and `@ThreadSafe`, indicating both its evolving nature and its guarantee of concurrent access safety.

### Core Responsibilities and Interface Design

The Session interface exposes eight primary responsibility areas through clearly defined method signatures. In [`api/maven-api-core/src/main/java/org/apache/maven/api/Session.java`](https://github.com/apache/maven/blob/main/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java), the API provides access to Maven version information via `getMavenVersion()` and effective settings through `getSettings()`, returning the immutable `Settings` configuration object that controls the current execution environment.

### Thread Safety and Experimental Status

The `@ThreadSafe` annotation on the Session interface guarantees that implementations can be shared across parallel builds controlled by `getDegreeOfConcurrency()`. However, the `@Experimental` annotation warns that the API may evolve between minor versions, requiring careful version management for plugins that depend on newer Session features.

## Key Capabilities of MavenSession

The Session aggregates multiple subsystems into a unified API, eliminating the need for direct service instantiation.

### Repository Management

Session provides first-class access to repository configuration through `getLocalRepository()` and `getRemoteRepositories()`, returning the configured local repository path and the list of remote repositories respectively. For ad-hoc repository creation, the interface offers `createLocalRepository(...)` and `createRemoteRepository(...)` factory methods.

### Project and Property Access

Through `getProjects()`, the Session exposes the list of `Project` objects currently participating in the build. The `getEffectiveProperties(...)` method computes hierarchical property maps following system → project → user precedence, essential for accurate configuration resolution.

### Service Locator Pattern and DI Integration

The Session implements a service locator pattern via `getService(Class<T>)`, where `T extends Service`. This generic method resolves any Maven service implementation—such as `ArtifactResolver` or `DependencyResolver`—from the underlying dependency injection container without explicit wiring.

### Artifact and Dependency Resolution

Convenience methods delegate to specialized services while keeping consumer code concise. `createArtifactCoordinates(...)` parses coordinate strings, `resolveArtifact(...)` downloads artifacts to the local repository, and `collectDependencies(...)` builds the transitive dependency graph for a given project and scope.

### Event Listener Registration

The Session maintains a registry of build listeners through `registerListener(...)`, `unregisterListener(...)`, and `getListeners()`. These methods accept `Listener` implementations that receive lifecycle events, enabling custom logging, metrics collection, or build orchestration logic.

## MavenSession Implementation and DI Scope

The concrete Session implementation is assembled by Maven's dependency-injection container, backed by a custom `SessionScope` that manages instance lifecycle and caching.

### The SessionScope Implementation

In [`impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java`](https://github.com/apache/maven/blob/main/impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java), Maven implements its own `org.apache.maven.di.Scope` interface. This class maintains a stack of `ScopeState` objects, each holding a map of cached providers. When a component is requested, the scope enters a new state via `enter()`, seeds explicit instances through `seed(Class<T>, Supplier<T>)`, and creates lazy-evaluation proxies for unscoped objects via `createProxy`.

### Guice Integration and Proxy Creation

The Guice bridge located at [`impl/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java) extends the Maven DI scope to adapt Guice's `Key`/`Provider` API to the internal `org.apache.maven.di.Key`. This bridge widens accepted annotations to include Sisu and Jakarta EE equivalents, ensuring compatibility across different dependency injection styles while maintaining the proxy mechanism for optional components.

### Scope State Management and Caching

The `SessionScope` implements a `CachingProvider` pattern that guarantees a single instance per session. After the first call to a provider, subsequent requests return the cached instance. This mechanism ensures that expensive service objects like `ArtifactResolver` are instantiated once per build phase and properly released when `exit()` is called.

## MavenSession Lifecycle in Build Execution

The Session lifecycle follows four distinct phases:

1. **Container Bootstrap**: Maven creates a `PlexusContainer` (powered by Guice) and registers the `SessionScope` with the DI container.
2. **Session Creation**: The `DefaultMaven` class builds a `DefaultSession` implementation (located in [`impl/maven-core/src/main/java/org/apache/maven/impl/session/DefaultSession.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/impl/session/DefaultSession.java)), populating it with core services via the DI container.
3. **Scope Activation**: At the start of each Mojo execution, Maven calls `SessionScope.enter()`, making all requested objects resolve against the active `ScopeState`.
4. **Scope Exit**: After Mojo completion, `SessionScope.exit()` discards the state, releasing references for garbage collection and ensuring clean resource management.

## Practical Code Examples for Advanced Use Cases

The following examples demonstrate advanced MavenSession patterns for plugin development:

```java
// 1️⃣ Retrieve the current Maven Session inside a Mojo
@Parameter(defaultValue = "${session}", readonly = true)
private Session session;

// 2️⃣ Resolve an artifact coordinates string
ArtifactCoordinates coords = session.createArtifactCoordinates(
        "org.apache.commons:commons-lang3:3.14.0");

// 3️⃣ Resolve the artifact file (downloads if necessary)
DownloadedArtifact resolved = session.resolveArtifact(coords);
Path artifactPath = resolved.getPath();

// 4️⃣ Collect the transitive dependency graph of a project
Node graph = session.collectDependencies(project, PathScope.compile());

// 5️⃣ Get the effective properties for a project (system + user + project)
Map<String, String> effectiveProps = session.getEffectiveProperties(project);

// 6️⃣ Register a listener to be notified of all lifecycle events
session.registerListener(event -> System.out.println("Maven event: " + event));

// 7️⃣ Create a derived Session that uses a different local repository
LocalRepository altLocal = session.createLocalRepository(Paths.get("/tmp/m2repo"));
Session altSession = session.withLocalRepository(altLocal);

```

## Summary

- The MavenSession API in `org.apache.maven.api.Session` provides a thread-safe façade to build-time state, repository configuration, and core services.
- **SessionScope** manages the lifecycle of Session-scoped objects through a custom DI implementation in [`impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java`](https://github.com/apache/maven/blob/main/impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java), with a Guice bridge in `impl/maven-core`.
- The Session supports **derived sessions** via `withLocalRepository()` and `withRemoteRepositories()`, enabling isolated sub-builds with different repository configurations.
- **Service lookup** through `getService(Class<T>)` provides type-safe access to `ArtifactResolver`, `DependencyResolver`, and other Maven services without explicit dependency injection configuration.
- The Session lifecycle enters a new scope state at each Mojo execution, ensuring proper caching and garbage collection of build-scoped objects.

## Frequently Asked Questions

### How do I access the current MavenSession inside a Mojo?

Inject the Session using the `@Parameter` annotation with `defaultValue = "${session}"` and `readonly = true`. This exposes the active `org.apache.maven.api.Session` instance that contains the current build state, settings, and repository configuration.

### What is the difference between SessionScope in maven-impl and maven-core?

The [`impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java`](https://github.com/apache/maven/blob/main/impl/maven-impl/src/main/java/org/apache/maven/impl/di/SessionScope.java) contains Maven's native DI scope implementation with `ScopeState` management and caching logic. The [`impl/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java) serves as a Guice bridge that adapts Guice's `Key` and `Provider` APIs to Maven's internal DI model, enabling compatibility with Sisu and Jakarta EE annotations.

### Can MavenSession be shared across parallel builds?

Yes, the Session is annotated with `@ThreadSafe` and can be shared across parallel builds controlled by `getDegreeOfConcurrency()`. The SessionScope implementation ensures thread-safe access to cached providers, though derived sessions created via `withLocalRepository()` provide isolation for specific build segments.

### How do I resolve artifacts programmatically using MavenSession?

Use `session.createArtifactCoordinates(String)` to parse coordinate strings, then call `session.resolveArtifact(ArtifactCoordinates)` to download and resolve the artifact to the local repository. This delegates to the `ArtifactResolver` service available via `session.getService(ArtifactResolver.class)`.