# Understanding Maven's Execution: 6 Core Files Every Developer Should Know

> Master Maven execution by exploring 6 essential Java files. Understand how Maven runs and optimize your build process for better development.

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

---

**The six key files that control Maven's execution are [`MavenCli.java`](https://github.com/apache/maven/blob/main/MavenCli.java), [`MavenExecutionRequest.java`](https://github.com/apache/maven/blob/main/MavenExecutionRequest.java), [`Maven.java`](https://github.com/apache/maven/blob/main/Maven.java), [`DefaultMaven.java`](https://github.com/apache/maven/blob/main/DefaultMaven.java), [`MavenSession.java`](https://github.com/apache/maven/blob/main/MavenSession.java), and [`GraphBuilder.java`](https://github.com/apache/maven/blob/main/GraphBuilder.java), which handle everything from CLI parsing to reactor graph construction.**

Apache Maven orchestrates Java builds through a sophisticated execution pipeline defined in the `apache/maven` repository. Understanding Maven's execution requires tracing how command-line arguments transform into a running build session through a specific chain of core classes. This guide examines the essential source files responsible for initializing, configuring, and executing your Maven projects.

## Entry Point and Request Initialization

The execution journey begins with parsing user input and constructing a configuration object that travels through the entire build pipeline.

### MavenCli.java: The Command-Line Interface

Located at [`compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java`](https://github.com/apache/maven/blob/main/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java), this class serves as the primary entry point for the `mvn` command. It parses CLI options, configures logging, loads core extensions, and ultimately constructs a `MavenExecutionRequest` before calling `Maven.execute`. Studying this file reveals how user input translates into structured execution parameters.

### MavenExecutionRequest.java: The Configuration Container

The interface at [`impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java) holds all configuration for a build, including goals, properties, repositories, profiles, and concurrency settings. Every option you specify on the command line—from `-DskipTests` to `-T 4`—ends up in this request object that downstream components consume throughout the build.

## Execution Orchestration

Once the request is built, Maven delegates to a facade that coordinates the heavy lifting of session creation and lifecycle execution.

### Maven.java: The Public API Facade

The interface at [`impl/maven-core/src/main/java/org/apache/maven/Maven.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/Maven.java) provides a simple contract with a single `execute(MavenExecutionRequest)` method. This abstraction enables easy testing and extension while hiding the complexity of the underlying implementation.

### DefaultMaven.java: Core Implementation

The concrete implementation at [`impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java) performs the actual orchestration. This class creates the `RepositorySystemSession`, builds the `MavenSession`, fires lifecycle events, constructs the reactor graph via `GraphBuilder`, and finally invokes `LifecycleStarter`. This is where the execution pipeline truly comes together, bridging configuration and runtime.

## Runtime State and Dependency Resolution

During execution, Maven maintains state and determines build order through specialized classes that manage project relationships.

### MavenSession.java: Build State Container

Found at [`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), this class holds the runtime state of a running build including the original request, execution result, top-level project, list of projects, dependency graph, and plugin contexts. Lifecycle listeners and participants receive this session object, making it crucial for understanding what data is available during plugin execution.

### GraphBuilder.java: Reactor Construction

The class at [`impl/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java) constructs the `ProjectDependencyGraph` from the list of `MavenProject` instances, applying selectors like `--projects` and `--also-make`. This graph determines the order in which modules are built and serves as the foundation for parallel builds and reactor-based dependency resolution.

## Programmatic Execution Example

You can run Maven's execution engine directly without invoking the CLI. This example demonstrates building a request and executing it programmatically:

```java
import org.apache.maven.Maven;
import org.apache.maven.impl.DefaultMaven;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;

// Build the request (equivalent to "mvn clean install -DskipTests")
MavenExecutionRequest request = new DefaultMavenExecutionRequest();
request.setGoals(List.of("clean", "install"));
request.getUserProperties().setProperty("skipTests", "true");

// Obtain a Maven implementation (normally injected via DI)
Maven maven = new DefaultMaven(
        lookup,          // org.apache.maven.api.services.Lookup
        eventCatapult,   // ExecutionEventCatapult
        legacySupport,   // LegacySupport
        sessionScope,
        repositorySessionFactory,
        graphBuilder,
        buildResumptionAnalyzer,
        buildResumptionDataRepository,
        superPomProvider,
        defaultSessionFactory,
        null /* ideWorkspaceReader */);

// Execute the build
MavenExecutionResult result = maven.execute(request);

// Check the outcome
if (result.hasExceptions()) {
    result.getExceptions().forEach(Throwable::printStackTrace);
} else {
    System.out.println("Build succeeded!");
}

```

After execution, inspect the session to examine reactor details:

```java
MavenSession session = result.getSession();
System.out.println("Top directory: " + session.getTopDirectory());
System.out.println("Projects in reactor:");
session.getProjects().forEach(p -> System.out.println(" - " + p.getId()));
System.out.println("Dependency graph: " + session.getProjectDependencyGraph());

```

## Summary

Understanding Maven's execution requires studying these six interconnected components:

- **[`MavenCli.java`](https://github.com/apache/maven/blob/main/MavenCli.java)** parses command-line arguments and initializes the execution request at [`compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java`](https://github.com/apache/maven/blob/main/compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java)
- **[`MavenExecutionRequest.java`](https://github.com/apache/maven/blob/main/MavenExecutionRequest.java)** encapsulates all build configuration at [`impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java)
- **[`Maven.java`](https://github.com/apache/maven/blob/main/Maven.java)** provides the public execution API at [`impl/maven-core/src/main/java/org/apache/maven/Maven.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/Maven.java)
- **[`DefaultMaven.java`](https://github.com/apache/maven/blob/main/DefaultMaven.java)** implements the core orchestration logic at [`impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java)
- **[`MavenSession.java`](https://github.com/apache/maven/blob/main/MavenSession.java)** maintains runtime build state at [`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)
- **[`GraphBuilder.java`](https://github.com/apache/maven/blob/main/GraphBuilder.java)** constructs the reactor dependency graph at [`impl/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java`](https://github.com/apache/maven/blob/main/impl/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java)

## Frequently Asked Questions

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

**`MavenExecutionRequest`** is the input configuration containing user-specified goals, properties, and profiles, while **`MavenSession`** is the runtime state container that includes the request, execution results, project list, and dependency graph. The request represents what you want to build; the session represents the actual running build state.

### How does Maven determine the order of module builds?

Maven uses **[`GraphBuilder.java`](https://github.com/apache/maven/blob/main/GraphBuilder.java)** to construct a `ProjectDependencyGraph` from the reactor projects, analyzing inter-module dependencies and applying CLI selectors like `--projects`. This graph determines the topological order for sequential builds and provides the basis for parallel execution threads.

### Can I run Maven programmatically without using the CLI?

Yes, you can instantiate **[`DefaultMaven.java`](https://github.com/apache/maven/blob/main/DefaultMaven.java)** directly and call `execute()` with a manually constructed **`DefaultMavenExecutionRequest`**. This approach is useful for embedding Maven in IDEs, CI systems, or custom build tools, bypassing the [`MavenCli.java`](https://github.com/apache/maven/blob/main/MavenCli.java) entry point entirely.

### Where does Maven handle command-line argument parsing?

Command-line parsing occurs in **[`MavenCli.java`](https://github.com/apache/maven/blob/main/MavenCli.java)** within the `compat/maven-embedder` module. This class converts raw CLI arguments into a structured **`MavenExecutionRequest`**, handling options like `-D` properties, `-P` profiles, and `-T` threading before delegating to the core execution engine.