# Jenkins Artifact Management with Maven: How the ArtifactManager Framework Handles Build Outputs

> Master Jenkins artifact management with Maven. Learn how ArtifactManager handles build outputs and stores them efficiently to streamline your CI CD workflow.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: how-to-guide
- Published: 2026-07-30

---

**Jenkins delegates all artifact storage to the `ArtifactManager` API, where `StandardArtifactManager` writes files to `$JENKINS_HOME` by default, while the Maven builder (`hudson.tasks.Maven`) produces the build outputs that `ArtifactArchiver` later collects and stores.**

The jenkinsci/jenkins repository separates the concerns of *how* Maven runs from *where* its outputs are stored. When you configure Jenkins artifact management with Maven, the build proceeds through distinct phases: the Maven builder executes goals and places files in the workspace, then the artifact manager handles persistence via a pluggable backend architecture.

## How the Maven Builder Configures the Build Environment

The Maven builder, implemented in [`core/src/main/java/hudson/tasks/Maven.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tasks/Maven.java), is a standard `Builder` that prepares the Maven execution context before any artifacts are produced. Its constructor captures the build configuration:

```java
public Maven(String targets,
             String name,
             String pom,
             String properties,
             String jvmOptions,
             boolean usePrivateRepository,
             SettingsProvider settings,
             GlobalSettingsProvider globalSettings,
             boolean injectBuildVariables) { … }

```

Key fields determine how Maven interacts with the workspace:

- **`targets`** – Maven goals such as `clean install` that produce JARs and WARs.
- **`usePrivateRepository`** – Enables `-Dmaven.repo.local=<workspace>/.repository` to isolate dependencies per build.
- **`settings` / `globalSettings`** – References to `SettingsProvider` implementations that supply [`settings.xml`](https://github.com/jenkinsci/jenkins/blob/main/settings.xml); fall back to `GlobalMavenConfig` when null.
- **`injectBuildVariables`** – When true, Jenkins automatically passes build variables as Maven properties (`-Dkey=value`).

During execution, the builder resolves the `MavenInstallation` via `getMaven()` and launches the process through a `Launcher`. Once Maven completes, control passes to post-build steps, typically beginning with `ArtifactArchiver`.

## The Artifact Archiving Pipeline

When a job includes the **"Archive the artifacts"** post-build action, Jenkins instantiates `ArtifactArchiver` from [`core/src/main/java/hudson/tasks/ArtifactArchiver.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tasks/ArtifactArchiver.java). Its `perform` method delegates to the active artifact manager:

```java
build.pickArtifactManager().archive(
        ws,
        launcher,
        BuildListenerAdapter.wrap(listener),
        files);

```

The `files` parameter is a `Map<String,String>` mapping workspace-relative paths to archive-relative destinations. The manager selection occurs at runtime through `Run.pickArtifactManager()` in [`core/src/main/java/hudson/model/Run.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/Run.java).

### StandardArtifactManager: The Default On-Disk Implementation

If no custom manager claims the build, `pickArtifactManager()` returns a `StandardArtifactManager` instance:

```java
return new StandardArtifactManager(this);

```

Located in [`core/src/main/java/jenkins/model/StandardArtifactManager.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/model/StandardArtifactManager.java), this implementation writes artifacts to `$JENKINS_HOME/jobs/<job>/builds/<buildNumber>/archive`. It exposes three core operations:

- **`archive(FilePath workspace, …)`** – Copies files from the workspace to the build-specific archive directory.
- **`delete()`** – Removes the entire archive directory for the build.
- **`root()`** – Returns a `VirtualFile` representing the archive root for UI browsing and API access.

Compression behavior is controlled by the `StandardArtifactManager.TAR_COMPRESSION` setting.

### Custom Artifact Managers via Factory Pattern

Plugins can replace the default storage backend by implementing `ArtifactManagerFactory` from [`core/src/main/java/jenkins/model/ArtifactManagerFactory.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/model/ArtifactManagerFactory.java). The system iterates through registered factories in `ArtifactManagerConfiguration` (located in [`core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java)) to select the first compatible manager:

```java
for (ArtifactManagerFactory f : ArtifactManagerConfiguration.get().getArtifactManagerFactories()) {
    ArtifactManager mgr = f.managerFor(this);
    if (mgr != null) return mgr;
}

```

This pattern enables external storage such as S3, Artifactory, or Azure Blob without modifying the Maven build configuration.

## Maven-Specific Artifact Flow

Maven builds follow a predictable path through the artifact management system:

1. **Production Phase** – The Maven builder executes `mvn clean install`, generating JARs, WARs, and POMs inside `target/` directories within the workspace.
2. **Collection Phase** – `ArtifactArchiver` evaluates patterns like `**/target/*.jar` against the workspace and constructs the file map.
3. **Storage Phase** – The selected `ArtifactManager` persists files to the configured backend, whether local disk or remote storage.
4. **Retrieval Phase** – The Jenkins UI renders the artifact tree via `Run.getArtifactManager().root()`, allowing direct downloads of specific files.

Because the `ArtifactManager` interface is agnostic to the build tool, the same archiving infrastructure handles Maven, Gradle, and shell script outputs uniformly.

## Configuration Examples

### Freestyle Job XML Configuration

The following configuration uses the Maven builder with a private repository and archives all JAR files produced in `target/` directories:

```xml
<project>
  <builders>
    <hudson.tasks.Maven>
      <targets>clean install</targets>
      <mavenName>DefaultMaven</mavenName>
      <pom>pom.xml</pom>
      <properties></properties>
      <usePrivateRepository>true</usePrivateRepository>
    </hudson.tasks.Maven>
  </builders>

  <publishers>
    <hudson.tasks.ArtifactArchiver>
      <artifacts>**/target/*.jar</artifacts>
      <allowEmptyArchive>false</allowEmptyArchive>
      <onlyIfSuccessful>true</onlyIfSuccessful>
      <fingerprint>false</fingerprint>
      <defaultExcludes>true</defaultExcludes>
      <caseSensitive>true</caseSensitive>
    </hudson.tasks.ArtifactArchiver>
  </publishers>
</project>

```

*The `usePrivateRepository` element ensures each build uses an isolated local Maven repository under the workspace.*

### Declarative Pipeline Configuration

In a Jenkins Pipeline, the `archiveArtifacts` step wraps the `ArtifactArchiver` functionality and automatically uses the currently configured `ArtifactManager`:

```groovy
pipeline {
    agent any
    tools {
        maven 'DefaultMaven'
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean install -Dmaven.repo.local=$WORKSPACE/.m2/repository'
            }
        }
    }
    post {
        success {
            archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
        }
    }
}

```

*The `tools` directive references a Maven installation defined in **Global Tool Configuration**, while the `post` section ensures artifacts are only archived for successful builds.*

## Summary

- **Separation of concerns** – The Maven builder (`hudson.tasks.Maven`) handles compilation and packaging, while `ArtifactArchiver` and `ArtifactManager` handle persistence.
- **Default storage** – `StandardArtifactManager` writes to `$JENKINS_HOME/jobs/<job>/builds/<#>/archive` unless overridden.
- **Pluggable backends** – Custom implementations via `ArtifactManagerFactory` allow cloud storage without changing job definitions.
- **Workspace isolation** – The `usePrivateRepository` option prevents dependency conflicts between concurrent Maven builds.
- **Source locations** – Core logic resides in [`core/src/main/java/hudson/tasks/Maven.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tasks/Maven.java), [`core/src/main/java/jenkins/model/StandardArtifactManager.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/model/StandardArtifactManager.java), and [`core/src/main/java/hudson/tasks/ArtifactArchiver.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/tasks/ArtifactArchiver.java).

## Frequently Asked Questions

### Where does Jenkins store Maven artifacts by default?

By default, Jenkins stores Maven artifacts in the local file system under `$JENKINS_HOME/jobs/<job-name>/builds/<build-number>/archive` using `StandardArtifactManager`. This location is accessible through the build's **Artifacts** page in the web UI and via the REST API through `Run.getArtifactManager().root()`.

### How do I configure a custom artifact manager for Maven builds?

Install a plugin that provides an `ArtifactManagerFactory` implementation (such as the S3 Artifact Manager). Navigate to **Manage Jenkins > Configure System**, locate the **Artifact Management for Builds** section, and select your custom manager. When `Run.pickArtifactManager()` executes, it will select your factory instead of the default `StandardArtifactManager`, redirecting all Maven build artifacts to the external storage backend.

### What is the difference between the Maven builder and the ArtifactArchiver?

The **Maven builder** (`hudson.tasks.Maven`) is a build step that executes Maven goals and populates the workspace with compiled outputs. The **ArtifactArchiver** (`hudson.tasks.ArtifactArchiver`) is a post-build step that collects files matching specified patterns and delegates them to the active `ArtifactManager` for persistent storage. The builder produces artifacts; the archiver persists them.

### How does Jenkins handle Maven settings.xml during artifact archiving?

While `ArtifactArchiver` does not directly interact with [`settings.xml`](https://github.com/jenkinsci/jenkins/blob/main/settings.xml), the Maven builder uses the `SettingsProvider` interface (configured in the job or inherited from `GlobalMavenConfig` in [`core/src/main/java/jenkins/mvn/GlobalMavenConfig.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/jenkins/mvn/GlobalMavenConfig.java)) to determine repository authentication and deployment settings during the build phase. These settings influence which artifacts Maven produces in the workspace, but the archiving phase itself is settings-agnostic and simply stores whatever files Maven leaves in `target/` directories.