---
url: /en/artifact/maven.md
description: >
  Guide for configuring credentials and using the CNB Maven artifact registry to
  push and pull Java/JVM packages with Maven or Gradle, covering local
  development and CI pipeline workflows.
---
## Prerequisites

1. [Create Artifact Registry](./intro.md#creating-an-artifact-registry)
2. [Obtain Artifact Registry Address](./intro.md#obtaining-the-artifact-registry-address)
3. [Create Access Token](./intro.md#creating-an-access-token)

## Local Development

### Configure Credentials

#### Maven

Copy the following content into the settings.xml file, replace `<YOUR_TOKEN>` with your token,
and `<REPO_URL>` with the Artifact Registry address.

```xml
<settings>
  <servers>
    <server>
      <id>cnb-maven-repo</id>
      <username>cnb</username>
      <!-- Replace with your access token -->
      <password><YOUR_TOKEN></password>
    </server>
  </servers>
  <profiles>
    <profile>
      <id>cnb-maven-repo-profile</id>
      <repositories>
        <repository>
          <!-- Must match the server's id -->
          <id>cnb-maven-repo</id>
          <!-- Replace with the Artifact Registry address -->
          <!-- Example
          <url>https://maven.cnbprod.alpha.qq.com/cnb/maven-repo/-/packages/</url>
          -->
          <url><REPO_URL></url>
        </repository>
      </repositories>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
  </profiles>
</settings>
```

#### Gradle kotlin

1. Configure the token in gradle.properties in the project root directory, replace `<YOUR_TOKEN>` with your token.

```properties
cnbArtifactsGradlePassword=<YOUR_TOKEN>
```

2. Paste the following content into build.gradle.kts, replace `<REPO_URL>` with the Artifact Registry address.

```kotlin
publishing {
    repositories {
        maven {
            val cnbArtifactsGradlePassword = project.findProperty("cnbArtifactsGradlePassword")

            // Example
            // url = uri("https://maven.cnbprod.alpha.qq.com/cnb/maven-repo/-/packages/")
            url = uri("<REPO_URL>")
            credentials {
                username = "cnb"
                password = cnbArtifactsGradlePassword.toString()
            }
        }
    }
}
```

#### Gradle groovy

1. Configure the token in gradle.properties in the project root directory, replace `<YOUR_TOKEN>` with your token.

```properties
cnbArtifactsGradlePassword=<YOUR_TOKEN>
```

2. Paste the following content into build.gradle, replace `<REPO_URL>` with the Artifact Registry address.

```groovy
publishing {
      repositories {
        maven {
            def cnbArtifactsGradlePassword = project.findProperty('cnbArtifactsGradlePassword')

            // Example
            // url = uri("https://maven.cnbprod.alpha.qq.com/cnb/maven-repo/-/packages/")
            url = uri('<REPO_URL>')
            credentials {
                username = 'cnb'
                password = cnbArtifactsGradlePassword.toString()
            }
        }
    }
}
```

### Pull Artifacts

#### Maven

1. Configure the package you need to pull in pom.xml.

```xml
<dependencies>
    <dependency>
        <groupId>[GROUP_ID]</groupId>
        <artifactId>[ARTIFACT_ID]</artifactId>
        <version>[VERSION]</version>
    </dependency>
</dependencies>

<!-- Example
<dependencies>
    <dependency>
        <groupId>org.cnb</groupId>
        <artifactId>maven_demo</artifactId>
        <version>9.0.0</version>
    </dependency>
</dependencies> -->
```

2. Pull artifacts.

```shell
mvn clean install
# If using a specific settings.xml, execute:
mvn clean install -s ./settings.xml
```

#### Gradle kotlin

1. Configure the dependencies you need in build.gradle.kts.

```kotlin
dependencies {
  implementation("[GROUP_ID]:[ARTIFACT_ID]:[VERSION]")
}

// Example
// dependencies {
//  implementation("com.google.guava:guava:32.1.3-jre")
// }
```

2. Pull artifacts.

```bash
./gradlew build --refresh-dependencies
```

#### Gradle groovy

1. Configure the dependencies you need in build.gradle.

```groovy
dependencies {
    implementation '[GROUP_ID]:[ARTIFACT_ID]:[VERSION]'
}

// Example
// dependencies {
//   implementation 'com.google.guava:guava:32.1.3-jre'
// }
```

2. Pull artifacts.

```bash
./gradlew build --refresh-dependencies
```

### Push Artifacts

#### Maven

1. Configure the publishing repository and artifact properties in pom.xml,
   replace `<REPO_URL>` with the Artifact Registry address.

```xml
<project>
  <modelVersion>4.0.0</modelVersion>
  <!-- Artifact properties -->
  <groupId>[GROUP_ID]</groupId>
  <artifactId>[ARTIFACT_ID]</artifactId>
  <version>[VERSION]</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <!-- Publishing repository -->
  <distributionManagement>
    <repository>
      <!-- Must match the server's id in settings.xml -->
      <id>cnb-maven-repo</id>
      <name>cnb-maven-repo</name>
      <!-- Example
      <url>https://maven.cnbprod.alpha.qq.com/cnb/maven-repo/-/packages/</url>
      -->
      <url><REPO_URL></url>
    </repository>
  </distributionManagement>
</project>
```

2. Push artifacts.

```shell
mvn deploy
# If using a specific settings.xml, execute:
mvn deploy -s ./settings.xml
```

#### Gradle kotlin

1. Paste the following content into build.gradle.kts.

```kotlin
plugins {
    `java-library`
    `maven-publish`
}

group = "[GROUP_ID]"
version = "[VERSION]"
val artifactName = "[ARTIFACT_ID]"

publishing {
    publications {
        create<MavenPublication>("myLibrary") {
            groupId = group.toString()
            version = version.toString()
            artifactId = artifactName
            from(components["java"])
        }
    }
}
```

2. Execute the upload command.

```shell
./gradlew publish
```

#### Gradle groovy

1. Paste the following content into build.gradle.

```groovy
plugins {
    id 'java-library'
    id 'maven-publish'
}

group = '[GROUP_ID]'
version = '[VERSION]'
def artifactName = '[ARTIFACT_ID]'

publishing {
    publications {
        myLibrary(MavenPublication) {
            groupId = group
            version = version
            artifactId = artifactName
            from components.java
        }
    }
}
```

2. Execute the upload command.

```shell
./gradlew publish
```

## Cloud Native Build

### Configure Credentials

In Cloud Native Build, use the built-in environment variable `CNB_TOKEN`.

::: tip Other Token Methods
To use plaintext tokens, replace `<YOUR_TOKEN>` with your token.
Or reference via a secret registry variable `<ENV_NAME>`.
See \[Using Tokens in Cloud Native Build and Development]
(./intro.md#using-tokens-in-workspaces-and-cloud-native-build) for details.
:::

#### Maven

Replace `<REPO_URL>` with the Artifact Registry address.

```xml
<settings>
  <servers>
    <server>
      <id>cnb-maven-repo</id>
      <username>cnb</username>
      <password>${env.CNB_TOKEN}</password>
      <!-- Alternative methods: -->
      <!--<password><YOUR_TOKEN></password>               Direct token -->
      <!--<password>${env.<ENV_NAME>}</password>          Secret registry -->
    </server>
  </servers>
  <profiles>
    <profile>
      <id>cnb-maven-repo-profile</id>
      <repositories>
        <repository>
          <!-- Must match the server's id -->
          <id>cnb-maven-repo</id>
          <url><REPO_URL></url>
        </repository>
      </repositories>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
  </profiles>
</settings>
```

#### Gradle kotlin

Replace `<REPO_URL>` with the Artifact Registry address.

```kotlin
publishing {
    repositories {
        maven {
            val cnbArtifactsGradlePassword = System.getenv("CNB_TOKEN")
            // Alternative methods:
            // val cnbArtifactsGradlePassword = "<YOUR_TOKEN>"           Direct token
            // val cnbArtifactsGradlePassword = System.getenv("ENV_NAME")   Secret registry

            url = uri("<REPO_URL>")
            credentials {
                username = "cnb"
                password = cnbArtifactsGradlePassword.toString()
            }
        }
    }
}
```

#### Gradle groovy

Replace `<REPO_URL>` with the Artifact Registry address.

```groovy
publishing {
      repositories {
        maven {
            def cnbArtifactsGradlePassword = System.getenv("CNB_TOKEN")
            // Alternative methods:
            // def cnbArtifactsGradlePassword = '<YOUR_TOKEN>'             Direct token
            // def cnbArtifactsGradlePassword = System.getenv("ENV_NAME")    Secret registry

            url = uri('<REPO_URL>')
            credentials {
                username = 'cnb'
                password = cnbArtifactsGradlePassword.toString()
            }
        }
    }
}
```

### Pull Artifacts

Paste the following content into `.cnb.yml`:

#### Maven

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: maven:3.8.5-openjdk-17
      stages:
        - name: mvn package
          script: mvn clean install -s ./settings.xml
```

#### Gradle

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: gradle:7.6.6-jdk17
      stages:
        - name: gradle build and run
          script: ./gradlew build --refresh-dependencies
```

### Push Artifacts

Paste the following content into `.cnb.yml`:

#### Maven

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: maven:3.8.5-openjdk-17
      stages:
        - name: mvn package
          script: mvn clean deploy -s ./settings.xml
```

#### Gradle

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: gradle:7.6.6-jdk17
      stages:
        - name: gradle publish
          script: ./gradlew publish
```

## Workspaces

### Configure Credentials

Same as [Cloud Native Build Configure Credentials](./maven.md#configure-credentials-1)

### Configure Development Image

```yaml title=".cnb.yml"
$:
  vscode:
    - docker:
        image: maven:3.8.5-openjdk-17
```

### Pull Artifacts

Same as [Local Development Pull Artifacts](./maven.md#pull-artifacts)

### Push Artifacts

Same as [Local Development Push Artifacts](./maven.md#push-artifacts)

## Examples

### Gradle Local Push AAR Package

1. Configure the android-library plugin in gradle/libs.versions.toml.

```toml
[versions]
agp = "8.11.1"
[plugins]
android-library = { id = "com.android.library", version.ref = "agp" }
```

2. Configure the aar packaging plugin and maven-publish plugin in build.gradle or build.gradle.kts.

#### Gradle kotlin

```kotlin
// build.gradle.kts
plugins {
    id("com.android.library") // AAR packaging plugin
    id("maven-publish")
}
```

#### Gradle groovy

```groovy
// build.gradle
plugins {
    id 'com.android.library'  // AAR packaging plugin
    id 'maven-publish'
}
```

3. Configure the build task and push address in build.gradle or build.gradle.kts.

#### Gradle kotlin

```kotlin
// build.gradle.kts
afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("releaseAar") {
                groupId = "cnb"
                artifactId = "artifact"
                version = "1.0.0"

                from(components["release"])
            }
        }
        repositories {
            maven {
                // Declare cnbArtifactsGradlePassword in gradle.properties or export CNB_TOKEN=${YOUR_TOKEN}
                val cnbArtifactsGradlePassword =
                    System.getenv("CNB_TOKEN") ?: project.findProperty("cnbArtifactsGradlePassword")

                // Example
                // url = uri("https://maven.cnbprod.alpha.qq.com/cnb/maven-repo/-/packages/")
                url = uri("<REPO_URL>")
                credentials {
                    username = "cnb"
                    password = cnbArtifactsGradlePassword.toString()
                }
            }
        }
    }
}
```

#### Gradle groovy

```groovy
// build.gradle
afterEvaluate {
    publishing {
        publications {
            releaseAar(MavenPublication) {
                groupId = 'cnb'
                artifactId = "artifact"
                version = '1.0.0'

                from components.release
            }
        }
        repositories {
            maven {
                // Declare cnbArtifactsGradlePassword in gradle.properties or export CNB_TOKEN=${YOUR_TOKEN}
                def cnbArtifactsGradlePassword =
                    System.getenv('CNB_TOKEN') ?: project.findProperty('cnbArtifactsGradlePassword')

                // Example
                // url = uri("https://maven.cnbprod.alpha.qq.com/cnb/maven-repo/-/packages/")
                url = uri("<REPO_URL>")
                credentials {
                    username = 'cnb'
                    password = cnbArtifactsGradlePassword.toString()
                }
            }
        }
    }
}
```

4. Execute the following command.

```bash
./gradlew publish
```

## FAQ

### After overwriting an existing version, the dependency build still uses the pre-overwritten version?

This is Maven's default behavior: if the package exists in the local cache,
it will not be fetched from the remote repository. There are three solutions:

1. Use the `--update-snapshots` command to force Maven to check for updates
   of snapshot dependencies in the remote repository.
   This strategy only works for SNAPSHOT versions.

```bash
mvn clean package -U
```

2. Delete the local cache

```bash
# macOS and Linux default location: ~/.m2
# Windows default location: C:\Users\{username}\.m2\repository
# Or query with the following command:
mvn help:evaluate -Dexpression=settings.localRepository
```

3. Set the `updatePolicy` to `always` in settings.xml for the dependency repository.
   This strategy only works for SNAPSHOT versions.

```xml
<settings>
  <profiles>
    <profile>
      <id>cnb-maven-repo-profile</id>
      <repositories>
        <repository>
          <id>cnb-maven-repo</id>
          <url><REPO_URL></url>
          <!-- Configure snapshot pull policy -->
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
          </snapshots>
        </repository>
      </repositories>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
  </profiles>
</settings>
```

### Encountered 409 Forbidden?

You have already uploaded this package and overwriting is prohibited.
To overwrite, go to the corresponding artifact repository → Artifact Settings → Policy Management:

* To overwrite only SNAPSHOT versions, select `Maven Snapshot Strategy`.
* To overwrite both SNAPSHOT and RELEASE versions, select `Allow overwriting of all existing versions`.

## More Usage

For more Maven usage, refer to the official Maven documentation.
