# Exploring the Source Code of Maven API Modules: Architecture and Implementation

> Dive into the Maven API source code. Understand its service-oriented facade, session interface, SPI delegation, and core functionalities like XML parsing and dependency resolution.

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

---

**The Maven API modules provide a thin, service-oriented facade centered on the `Session` interface, delegating implementation details to discoverable SPI services while handling XML parsing, dependency graphs, and artifact resolution through dedicated sub-modules.**

The **Maven API modules** in the `apache/maven` repository organize Maven’s core functionality into a set of cohesive, programmatic interfaces. These modules expose only API surfaces—such as `Session`, `Project`, and `Artifact`—while the actual implementation logic resides in Maven’s internal runtime, discovered dynamically via Java’s `ServiceLoader` mechanism.

## Maven API Module Architecture Overview

The Maven API is deliberately partitioned into five distinct layers that separate concerns between model definition, extension points, and XML processing.

### Core Module

The **Core** module (`maven-api-core`) defines the central abstractions including `Session`, `Project`, `Artifact`, and `Repository`. Located 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), this layer provides convenience methods for common operations like artifact resolution and dependency collection. The `Session` interface acts as the primary façade, bundling build state and service access.

### SPI Module

The **SPI** module (`maven-api-spi`) supplies extension points and service contracts. Defined in [`api/maven-api-spi/src/main/java/org/apache/maven/api/spi/SpiService.java`](https://github.com/apache/maven/blob/main/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/SpiService.java), this layer specifies interfaces for `ArtifactResolver`, `DependencyResolver`, and `VersionResolver`. Implementations reside in `org.apache.maven.internal.*` packages and are loaded at runtime via `ServiceLoader`.

### XML Module

The **XML** module (`maven-api-xml`) handles Maven-specific XML processing through a streaming-based parser. The `XmlService` class, found in [`api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java`](https://github.com/apache/maven/blob/main/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java), provides `read()`, `write()`, and `merge()` operations. It supports Maven’s combine semantics via constants like `CHILDREN_COMBINATION_MERGE`, `combine.children`, and `combine.self`.

### Model Module

The **Model** module provides POJO representations of the Maven model (POMs and settings) alongside XPP3 serialization helpers. The merge logic for these objects is implemented in [`compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java`](https://github.com/apache/maven/blob/main/compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java), which handles deep merging of model objects according to Maven’s inheritance rules.

### Builder-Support Module

The **Builder-Support** module contains utilities for handling problems and filesystem artifacts during the build process. The `DefaultProblemCollector` class in [`compat/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblemCollector.java`](https://github.com/apache/maven/blob/main/compat/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblemCollector.java) provides centralized error collection and reporting for model building and validation.

## The Session Interface: Central Entry Point

The **`Session`** interface represents a running Maven build and serves as the primary entry point for all API operations. 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 interface exposes:

- **Build environment**: `getMavenVersion()`, `getSettings()`, `getLocalRepository()`, `getRemoteRepositories()`
- **Project state**: `getProjects()` returns the list of projects in the current session
- **Service lookup**: `getService(Class<T>)` retrieves SPI implementations dynamically
- **Convenience shortcuts**: `createArtifactCoordinates()`, `resolveArtifact()`, `collectDependencies()`

All higher-level operations delegate to the appropriate service obtained through the session, ensuring plugin code remains decoupled from internal implementations.

## Service Provider Interfaces and Extension Points

The SPI layer defines contracts for extending Maven’s behavior without modifying the core. Key service interfaces include:

- **`ArtifactResolver`**: Locates and downloads artifacts from repositories
- **`DependencyResolver`**: Constructs dependency graphs and flattens them for specific scopes
- **`VersionResolver`**: Handles SNAPSHOT versions and version range resolution
- **`RepositoryFactory`**: Creates local and remote repository objects
- **`TypeRegistry` / `LanguageRegistry` / `PackagingRegistry`**: Resolve Maven-specific enums from string identifiers

Implementations are discovered through `XmlService.getService()` or `session.getService()`, which internally use Java’s `ServiceLoader` to find providers on the classpath.

## XML Processing and Model Merge Semantics

The **`XmlService`** provides a streaming-first approach to handling Maven’s XML structures (POMs, settings, toolchains).

### Streaming XML Operations

The service supports three primary operations:
- **`read(InputStream)`**: Parses XML into an `XmlNode` tree
- **`write(XmlNode, Writer)`**: Serializes nodes back to XML
- **`merge(XmlNode dominant, XmlNode recessive)`**: Combines two XML trees according to Maven’s combine rules

### Merge Behavior

When merging XML documents (such as overlaying user settings onto defaults), `XmlService` respects attributes defined in [`XmlService.java`](https://github.com/apache/maven/blob/main/XmlService.java):
- `combine.children` with values like `CHILDREN_COMBINATION_MERGE`
- `combine.self` for self-merge behavior
- `combine.id` and `combine.keys` for identifying merge targets

## Dependency Resolution Workflow

Resolving dependencies through the Maven API modules follows a consistent pattern:

1. **Obtain a `Session`** instance from the Maven launcher or test harness
2. **Retrieve the resolver** via `session.getService(DependencyResolver.class)`
3. **Collect the graph** using `session.collectDependencies(artifact, PathScope.compile())`, which returns a `Node` tree
4. **Flatten or resolve paths** with `session.resolveDependencies(root, PathScope.compile())` to obtain a list of filesystem paths
5. **Optional version resolution** for ranges and SNAPSHOTs via `session.resolveVersion(coords)`

The `Node` class represents a lightweight tree node storing an `Artifact` and its children, produced by `DependencyResolver.collect()` and traversed for flattening.

## Practical Code Examples

### Resolving a SNAPSHOT Artifact

```java
Session session = ...; // obtained from Maven launcher
ArtifactCoordinates coords = session.createArtifactCoordinates(
        "org.apache.maven", "maven-core", "3.9.0-SNAPSHOT", "jar");
DownloadedArtifact artifact = session.resolveArtifact(coords);
System.out.println("Resolved to: " + artifact.getPath());

```

*Source: `Session.resolveArtifact` 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)*

### Building a Project Programmatically

```java
Session session = ...;
Project project = session.getService(ProjectFactory.class)
        .create("com.example", "demo", "1.0.0", session.getLocalRepository());
project.addDependency(
        session.createArtifactCoordinates("org.apache.commons", "commons-lang3", "3.14.0", "jar"));
session.registerListener(event -> System.out.println("Event: " + event.type()));

```

*Source: `ProjectFactory` SPI and `Project` API in [`api/maven-api-core/src/main/java/org/apache/maven/api/Project.java`](https://github.com/apache/maven/blob/main/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java)*

### Merging Maven Settings Files

```java
XmlService xml = XmlService.getService();
XmlNode defaultSettings = xml.read(new FileInputStream("settings.xml"), null);
XmlNode userSettings = xml.read(new FileInputStream("user-settings.xml"), null);
XmlNode merged = xml.merge(userSettings, defaultSettings); // user overrides defaults
xml.write(merged, new FileWriter("merged-settings.xml"));

```

*Source: `XmlService.merge` in [`api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java`](https://github.com/apache/maven/blob/main/api/maven-api-xml/src/main/java/org/apache/maven/api/xml/XmlService.java)*

## Summary

- The **Maven API modules** are organized into five layers: Core, SPI, XML, Model, and Builder-Support, each with distinct responsibilities
- **`Session`** 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) serves as the central façade, providing access to settings, repositories, and generic service lookup
- **Service discovery** occurs via Java’s `ServiceLoader`, allowing the API to remain thin while implementations reside in `org.apache.maven.internal.*` packages
- **XML processing** uses `XmlService` for streaming parse, write, and merge operations following Maven’s combine semantics (e.g., `CHILDREN_COMBINATION_MERGE`)
- **Dependency resolution** leverages `DependencyResolver` and `Node` objects to construct and flatten dependency graphs without binding to specific implementation classes

## Frequently Asked Questions

### What is the primary entry point class in the Maven API modules?

The **`Session`** interface, located 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), serves as the primary entry point. It provides access to the Maven version, settings, local and remote repositories, and acts as a factory for retrieving SPI implementations via the `getService(Class<T>)` method.

### How does Maven discover implementations for the SPI interfaces?

Maven uses Java’s **`ServiceLoader`** mechanism to discover implementations at runtime. While the API modules define interfaces like `ArtifactResolver` and `DependencyResolver` in the SPI package, the concrete implementations reside in `org.apache.maven.internal.*` packages and are loaded dynamically when requested through the Session or `XmlService.getService()`.

### What are the merge semantics used by XmlService when combining XML documents?

The **`XmlService.merge()`** method follows Maven’s specific combine rules, using attributes like `combine.children`, `combine.self`, `combine.id`, and `combine.keys` defined as constants in [`XmlService.java`](https://github.com/apache/maven/blob/main/XmlService.java) (e.g., `CHILDREN_COMBINATION_MERGE`). These rules determine how dominant and recessive XML trees combine, with user settings typically overriding defaults while preserving structural integrity.

### Which module handles POJO representation of the POM structure?

The **Model** module provides the POJO representation of the Maven model, including POMs and settings files. While the API defines the interfaces, the concrete implementation and merge logic reside in [`compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java`](https://github.com/apache/maven/blob/main/compat/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java), which handles the deep merging of model objects according to Maven’s inheritance rules.