# Configure Java build tools

URL: https://chainguard-docs-preview-git-1016-404s.chainguard.app/chainguard/libraries/java/build-configuration.md
Last Modified: September 28, 2026
Tags: Chainguard Libraries, Java

Configuring Chainguard Libraries for Java on your workstation


Chainguard Libraries for Java works with your existing build tools — Maven,
Gradle, and Bazel — through a repository configuration change. This page is a
reference for configuring each supported build tool. It covers repository
access, authentication, cache clearing, and minimal example projects.

Apply these changes on every workstation and build server that builds your
applications or downloads libraries, including CI/CD infrastructure such as
Jenkins, TeamCity, or GitHub Actions.

The `https://libraries.cgr.dev/java/` endpoint is also the [Chainguard Repository](/chainguard/chainguard-repository/overview/) endpoint for Java. By default, it serves only Chainguard-built artifacts. When [upstream fallback](/chainguard/libraries/introduction/overview/#upstream-fallback-and-controls) is enabled for your organization, the same endpoint can also serve requested versions from Maven Central under Chainguard security controls.

This guide outlines how to configure your build tool. If you are looking for something else, refer to the following guides depending on your goals:

| If you want to... | Use this page |
| --- | --- |
| Understand what Chainguard Libraries for Java is and how it works | [Java overview](/chainguard/libraries/java/overview/) |
| Set up organization-wide access through a repository manager | [Global configuration](/chainguard/libraries/java/global-configuration/) |
| Migrate an existing project step by step | [Java migration guide](/chainguard/libraries/java/migration/) |
| Install inside a container build without leaking credentials into the image | [Container builds](/chainguard/libraries/policies-and-security/build-containers/) |

If a package or version is blocked by a policy or malware scan, your build tool returns an error. Refer to the [Error messages documentation](/chainguard/libraries/troubleshooting/errors/) for more details.

## Library access approaches

### Repo manager

#### Cloudsmith

Build configuration to retrieve artifacts from Cloudsmith requires you to
authenticate. Use your username and password for Cloudsmith in your build tool
configuration.

Follow the steps from the [global
configuration](/chainguard/libraries/java/global-configuration/#cloudsmith) to
determine URL and authentication details.

#### JFrog Artifactory

Build configuration to retrieve artifacts from Artifactory typically requires
you to authenticate and use the identity token in the configuration of your
build tool.

Follow the steps from the [global
configuration](/chainguard/libraries/java/global-configuration/#jfrog-artifactory)
to determine URL and authentication details.

#### Sonatype Nexus Repository

Build configuration to retrieve artifacts from Nexus may require authentication.
Use your username and password for Nexus in your build tool configuration.

Follow the steps from the [global
configuration](/chainguard/libraries/java/global-configuration/#sonatype-nexus-repository)
to determine URL and authentication details.

### Direct access

Build configuration to retrieve artifacts **directly** from the Chainguard
Libraries
for Java repository requires authentication
with username and password from a pull token as detailed in
[access documentation](/chainguard/libraries/introduction/access/#pull-token).

If using Chainguard's [CVE remediation](/chainguard/libraries/policies-and-security/cve-remediation/) for Java libraries (available in beta), set it as the top repository. The recommended ordering for repositories is:

1. `https://libraries.cgr.dev/java-remediated/` for remediated Spring Boot libraries; this is available in beta as part of the [CVE remediation](/chainguard/libraries/policies-and-security/cve-remediation/) feature.
1. `https://libraries.cgr.dev/java/`
1. `https://repo1.maven.org/maven2/` or your Maven Central proxy

## Selecting remediated library versions

When using the [CVE remediation feature](/chainguard/libraries/policies-and-security/cve-remediation/), available in beta to Chainguard Libraries for Java, your build will not receive a remediated Java artifact automatically with the overlay repository configured. To use the remediated build, you must opt in to the suffixed version directly, or route resolution to it through dependency management, Gradle constraints, or version ranges.

### Update dependency version directly

For Maven, you can set the suffixed version as a dependency in your `pom.xml`. For example:

```xml
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.18.0-0.cgr.1</version>
</dependency>
```

For Gradle, you can set the suffixed version in the dependencies block in `build.gradle`:

```build.gradle
implementation 'org.apache.commons:commons-lang3:3.18.0-0.cgr.1'
```

### Override the version centrally

When you use this option, the remediated version will apply to both direct and transitive dependencies.

For Maven, update the `dependencyManagement` in a parent POM or the project POM:

```xml
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.18.0-0.cgr.1</version>
    </dependency>
  </dependencies>
</dependencyManagement>
```

For Gradle, update the `constraints` block in `build.gradle`:

```build.gradle
dependencies {
  constraints {
    implementation('org.apache.commons:commons-lang3:3.18.0-0.cgr.1') {
      because 'CVE remediation via Chainguard Libraries overlay'
    }
  }
}
```

## Apache Maven

[Apache Maven](https://maven.apache.org/) is the most widely used build tool in
the Java ecosystem. Dependencies are declared in a `pom.xml` file and resolved from remote repositories.

### Step 1: Remove Maven caches

Maven caches downloaded artifacts in a local repository. When adopting Chainguard Libraries
for Java you must delete that local cache so that libraries are re-downloaded
from Chainguard. By default the cache is located in a
hidden `.m2/repository` directory in your user's home directory. Use the
following command to delete it:

```shell
rm -rf ~/.m2/repository
```

### Step 2: Configure access

Before running a new build you must configure access to the Chainguard Libraries
for Java. There are two options for configuring Maven to use Chainguard
Libraries:

* Repository manager — routes all artifact requests through your organization's
  Artifactory, Nexus, or Cloudsmith instance
* Direct access — configures Chainguard Libraries directly in
  `~/.m2/settings.xml`, without a repository manager

<a name="repo-manager-maven"></a>

#### Configure access with a repository manager

Before running a new build you must configure access to Chainguard Libraries
for Java. If your organization uses a repository manager, configure a global mirror in `~/.m2/settings.xml` that routes all artifact requests through it.

A typical setup defines a global mirror (id `repo-example` in the following example) for all artifacts and
configures the URL of the repository group or virtual repository from your
repository manager `https://repo.example.com/group/`. Since the group or virtual
repository combines release and snapshot artifacts you must override the
built-in `central` repository and its configuration in an automatically
activated profile.

```xml
<settings>

  <mirrors>
    <mirror>
      <!-- Set the identifier for the server credentials for repository manager access -->
      <id>repo-example</id>
      <!-- Send all requests to the repository manager -->
      <mirrorOf>*</mirrorOf>
      <url>https://repo.example.com/repository/group</url>
      <!-- Cloudsmith example -->
      <!-- <url>https://dl.cloudsmith.io/basic/exampleorg/java-all/maven/</url> -->
      <!-- JFrog Artifactory example -->
      <!-- <url>https://example.jfrog.io/artifactory/java-all/</url> -->
      <!-- Sonatype Nexus example -->
      <!-- <url>https://repo.example.com:8443/repository/java-all/</url> -->
      <!-- Direct access example -->
      <!-- <url>https://libraries.cgr.dev/java/</url> -->
    </mirror>
  </mirrors>

  <!-- Activate repo manager and override central repo from Maven itself with invalid URLs -->
  <activeProfiles>
    <activeProfile>repo-manager</activeProfile>
  </activeProfiles>
  <profiles>
    <profile>
      <id>repo-manager</id>
      <repositories>
        <repository>
          <id>central</id>
          <url>http://central</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://central</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>true</enabled>
          </snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>

</settings>
```

**Setting credentials for the server**

If your repository manager requires authentication, you must specify credentials
for the server. The `id` value in the server element must match the `id` value
in the mirror configuration - `repo-example` in the example. The username
and password values vary depending on the repository manager and the configured
authentication; contact the administrator and refer to the [global configuration
documentation](/chainguard/libraries/java/global-configuration/).

```xml
<settings>
...
  <servers>
    <server>
      <id>repo-example</id>
      <username>YOUR_USERNAME_FOR_REPOSITORY_MANAGER</username>
      <password>YOUR_PASSWORD</password>
    </server>
  </servers>
</settings>
```

Note that you can use a secret manager application to populate the credentials
for each user on their workstation as well as for service applications in your
CI/CD pipelines into environment variables, for example `CHAINGUARD_JAVA_IDENTITY_ID`
and `CHAINGUARD_JAVA_TOKEN`. You can then use an identical server configuration, and
therefore settings file, for all users:

```xml
<settings>
...
  <servers>
    <server>
      <id>repo-example</id>
      <username>${env.CHAINGUARD_JAVA_IDENTITY_ID}</username>
      <password>${env.CHAINGUARD_JAVA_TOKEN}</password>
    </server>
  </servers>
</settings>
```

Refer to the [official documentation for the Maven settings
file](https://maven.apache.org/settings.html) for more details.

If the administrator only re-configured the existing repository group or virtual
repository, you can trigger a build to initiate use of Chainguard Libraries for
Java.

#### Configure direct access

If you are not using a repository manager at your organization, you can
configure access to the Chainguard Libraries for Java repository directly. If [upstream fallback](/chainguard/libraries/introduction/overview/#upstream-fallback-and-controls) is enabled for your organization, the `https://libraries.cgr.dev/java/` repository can serve both Chainguard-built artifacts and eligible upstream Maven Central artifacts through the same endpoint. If upstream fallback is not enabled, continue to configure Maven Central or your Maven Central proxy after the Chainguard repository, as shown in the following example.

If you are participating in the beta for CVE remediation, include the `https://libraries.cgr.dev/java-remediated/` repository first.

If you are using direct access with the Chainguard Repository and you want Chainguard policy controls to apply consistently, configure Chainguard as a global Maven mirror. Without a global mirror, Maven can fall back to its built-in Maven Central definition when Chainguard reports a dependency as unavailable, bypassing the policy and malware scanning controls provided by Chainguard.

The following `~/.m2/settings.xml` configures direct access with Chainguard's remediated Java repository as
the primary repository, falling back to the standard Chainguard Libraries repository when a remediated version is not available. If a library is not yet built by Chainguard and you have enabled upstream fallback, then upstream packages will be subject to malware scanning and any cooldown policies you have configured. This settings file uses [environment
variables](/chainguard/libraries/introduction/access/#env) for the pull token detailed in
[Chainguard Libraries access](/chainguard/libraries/introduction/access/).

```xml
<settings>
  <activeProfiles>
    <activeProfile>chainguard</activeProfile>
  </activeProfiles>

  <profiles>
    <profile>
      <id>chainguard</id>

      <repositories>
        <repository>
          <id>chainguard-remediated</id>
          <url>https://libraries.cgr.dev/java-remediated/</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>false</enabled></snapshots>
        </repository>
        <repository>
          <id>chainguard-java</id>
          <url>https://libraries.cgr.dev/java/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
        <repository>
          <id>central</id>
          <url>invalid</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>false</enabled></snapshots>
        </repository>
      </repositories>

      <pluginRepositories>
        <pluginRepository>
          <id>chainguard-java-remediated</id>
          <url>https://libraries.cgr.dev/java-remediated/</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>false</enabled></snapshots>
        </pluginRepository>
        <pluginRepository>
          <id>chainguard-java</id>
          <url>https://libraries.cgr.dev/java/</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>false</enabled></snapshots>
        </pluginRepository>
        <pluginRepository>
          <id>central</id>
          <url>invalid</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>false</enabled></snapshots>
        </pluginRepository>

      </pluginRepositories>
    </profile>
  </profiles>

    <mirrors>
    <mirror>
      <id>chainguard</id>
      <name>Chainguard Mirror</name>
      <url>https://libraries.cgr.dev/java/</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors>

  <servers>
    <server>
      <id>chainguard-remediated</id>
      <!-- Use environment variables -->
      <username>${env.CHAINGUARD_JAVA_IDENTITY_ID}</username>
      <password>${env.CHAINGUARD_JAVA_TOKEN}</password>
      <!-- <username>YOUR_IDENTITY_ID</username> -->
      <!-- <password>YOUR_TOKEN</password> -->
    </server>
      <id>chainguard-java</id>
      <!-- Use environment variables -->
      <username>${env.CHAINGUARD_JAVA_IDENTITY_ID}</username>
      <password>${env.CHAINGUARD_JAVA_TOKEN}</password>
      <!-- <username>YOUR_IDENTITY_ID</username> -->
      <!-- <password>YOUR_TOKEN</password> -->
    </server>
  </servers>
</settings>
```

The preceding settings affects all projects built on the machine where the file
is configured. Alternatively you can add the `repositories` and
`pluginRepositories` to individual project `pom.xml` files. Authentication
details must remain within the settings file.

If your `settings.xml` is using credentials set as environment variables, ensure the variables are exported.

>Note: Upstream fallback includes a 7-day cooldown by default. If you have a cooldown policy configured, your build will fail if a package falls within the cooldown window. Refer to [the FAQ](#build-fails-with-unknown-host-invalid-or-nodename-nor-servname-provided) on this page for more information.

### Minimal example project

Use the following steps to create a minimal example project for Maven with Chainguard Libraries for Java. For testing purposes, you can use direct access and environment variables as
detailed in the [access documentation](/chainguard/libraries/introduction/access/#use-environment-variables-for-pull-token-credentials).

**1. Remove the Maven cache**

Remove the Maven cache as described in the [Remove Maven
caches](#step-1-remove-maven-caches) section.

**2. Create a new Maven project**

This command generates a new Maven project from the `archetype` template, sets
the group ID and artifact ID, creates a full project structure, and then moves
into the generated project directory:

```bash
mvn archetype:generate \
  -DgroupId=com.example \
  -DartifactId=maven-example \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.5 \
  -DinteractiveMode=false
cd maven-example
```

**3. Add a dependency to pom.xml**

Add a dependency on `com.google.guava:guava` to the `<dependencies>` section of
`pom.xml`. Open the file and insert the following before the closing
`dependencies` tag:

```xml
<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>33.4.0-jre</version>
</dependency>
```

**4. Configure credentials**

Once the environment variables are set, configure credentials in `~/.m2/settings.xml`:

```bash
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << EOF
<settings>
  <activeProfiles>
    <activeProfile>no-repo-manager</activeProfile>
  </activeProfiles>
  <profiles>
    <profile>
      <id>no-repo-manager</id>
      <repositories>
        <repository>
          <id>chainguard</id>
          <url>https://libraries.cgr.dev/java/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
        <repository>
          <id>central</id>
          <url>https://repo1.maven.org/maven2/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>chainguard</id>
          <url>https://libraries.cgr.dev/java/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </pluginRepository>
        <pluginRepository>
          <id>central</id>
          <url>https://repo1.maven.org/maven2/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <servers>
    <server>
      <id>chainguard</id>
      <username>${env.CHAINGUARD_JAVA_IDENTITY_ID}</username>
      <password>${env.CHAINGUARD_JAVA_TOKEN}</password>
    </server>
  </servers>
</settings>
EOF
```

If you are using Chainguard's remediated repository for Java libraries, make sure to add `https://libraries.cgr.dev/java-remediated/` first, as shown in the [direct access example](#direct-access) earlier on this page.

**5. Build the project**

Then build the project:

```bash
mvn install
```

During the build, Maven logs each artifact download with the source repository.
Lines beginning with `Downloaded from chainguard:` confirm the artifact was
served by Chainguard Libraries. Lines beginning with `Downloaded from central:`
indicate that a dependency is not present in Chainguard and the download fell
back to Maven Central; this is expected behavior.

#### Verify the project works as expected

Following the build, the dependencies declared in `pom.xml` are downloaded to
the local Maven repository at ~/.m2/repository. For example, the `guava`
dependency added in the example project can be found at:

```
~/.m2/repository/com/google/guava/guava/33.4.0-jre/guava-33.4.0-jre.jar
```

To verify the artifact was built by Chainguard, use `chainctl`:

```bash
chainctl libraries verify \
  ~/.m2/repository/com/google/guava/guava/33.4.0-jre/guava-33.4.0-jre.jar
```

> **Note**: Running `chainctl libraries verify` requires the `libraries.java.pull` permission or the Owner role.

A successfully verified artifact produces output similar to the following:

```bash
Artifact: /Users/example/.m2/repository/com/google/guava/guava/33.4.0-jre/guava-33.4.0-jre.jar
Verification Coverage: 100.00%
```

Adjust the repository URL to use your repository manager and add any other
desired packages for further testing.

## Gradle

[Gradle](https://gradle.org/) is a commonly used build tool in the Java
ecosystem.

### Step 1: Remove Gradle caches

Gradle uses a local cache of libraries. When adopting Chainguard Libraries for
Java you must delete that local cache so that libraries
are downloaded again. By default the cache is located in a hidden
`~/.gradle/caches` directory in your user's home directory.

Use the following command to delete it:

```bash
rm -rf ~/.gradle/caches/
```

Gradle can also be configured to use a local Maven repository with a repository
configuration in the global `init.gradle` or a project specific `build.gradle`
file:

```groovy
repositories {
   ...
    mavenLocal()  
}
```

If this configuration is used, ensure you [delete the local Maven repository as
well](#step-1-remove-maven-caches).

### Step 2: Change Gradle configuration

Before running a new build you must configure access to the Chainguard Libraries
for Java. There are three options for configuring Gradle to use Chainguard
Libraries:

* Repository manager — routes all artifact requests through your organization's
  Artifactory, Nexus, or Cloudsmith instance
* Direct access — configures Chainguard Libraries as a repository in your build
  file, without a repository manager
* An [`init`
script](https://docs.gradle.org/current/userguide/init_scripts.html#sec:using_an_init_script)
— applies the repository configuration globally to all Gradle projects on a
machine

If the administrator for your organization’s repository manager created a new
repository or virtual repository or group repository, you must update your
Gradle configuration. Artifact download in Gradle can be configured in an
[`init`
script](https://docs.gradle.org/current/userguide/init_scripts.html#sec:using_an_init_script)
using the repositories definition. Each project can also [declare
repositories](https://docs.gradle.org/current/userguide/declaring_repositories_basics.html)
separately.

<a name="repo-manager-gradle"></a>

#### Using a repository manager

A typical setup removes the direct reference to Maven Central `mavenCentral()`
and any other repositories, and adds a replacement definition with the URL of the
repository group or virtual repository from your repository manager
`https://repo.example.com/group/` and any applicable authentication details.

Open `app/build.gradle` and update the `repositories` block to include the
following repository. Ensure it is located above the `mavenCentral` repository
and any other repositories:

```groovy
repositories {
    maven {
        url = uri("https://repo.example.com/group/")
        credentials {
            username = "YOUR_USERNAME_FOR_REPOSITORY_MANAGER"
            password = "YOUR_PASSWORD"
        }
    }
}
```

> **Note**: Do not store credentials directly in build files; use environment
>variables or local Gradle properties instead.

Example URLs for repository managers:

* Cloudsmith: `https://dl.cloudsmith.io/basic/exampleorg/java-all/maven/`
* JFrog Artifactory: `https://example.jfrog.io/artifactory/java-all/`
* Sonatype Nexus: `https://repo.example.com:8443/repository/java-all/`

#### Direct access to Chainguard Libraries

If your organization does not use a repository manager you can configure the
Chainguard Libraries for Java repository with the credentials from [Chainguard
Libraries access](/chainguard/libraries/introduction/access/). The following `repositories` block demonstrates
the recommended method of using [environment
variables](/chainguard/libraries/introduction/access/#use-environment-variables-for-pull-token-credentials)
for your pull token credentials.

Open `app/build.gradle` and update the `repositories` block to include the
Chainguard repository. Ensure it is located above the `mavenCentral` repository
and any other repositories. If you are using Chainguard's [remediated library repository](/chainguard/libraries/policies-and-security/cve-remediation/), set it as the top repository:

```groovy
repositories {
      maven {
    url = uri("https://libraries.cgr.dev/java-remediated/")
    credentials {
      username = providers.environmentVariable("CHAINGUARD_JAVA_IDENTITY_ID").orNull
      password = providers.environmentVariable("CHAINGUARD_JAVA_TOKEN").orNull
    }
  }

    maven {
        url = uri("https://libraries.cgr.dev/java/")
        credentials {
            username = providers.environmentVariable("CHAINGUARD_JAVA_IDENTITY_ID").orNull
            password = providers.environmentVariable("CHAINGUARD_JAVA_TOKEN").orNull
        }
    }
    mavenCentral()
}
```

#### Using an init script

The following listing shows a valid `init.gradle` file that applies the repository configuration globally using `~/.gradle/init.gradle`. It wraps the
`repositories` element with `allprojects` so that the scope of the file affects
all projects built locally with Gradle. It also allows for downloads for plugins
and build scripts from the remote URL using `buildscript`. Lastly the example
shows use of an internal repository manager that only serves artifacts without
authentication using HTTP only. Since this is not advisable unless other
networking setups allow a secure use with HTTP, the override with the property
`allowInsecureProtocol` is required:

```groovy
allprojects {
  buildscript {
    repositories {
      maven {
        url = "http://repo.example.com:8081/repository/java-all/"
        allowInsecureProtocol = true
      }
    }
  }
  repositories {
    maven {
        url = "http://repo.example.com:8081/repository/java-all/"
        allowInsecureProtocol = true
    }
  }
}
```

### Minimal example project

Use the following steps to create a minimal example project for Gradle with Chainguard Libraries for Java. For testing purposes, you can use direct access and environment variables as
detailed in the [access documentation](/chainguard/libraries/introduction/access/#use-environment-variables-for-pull-token-credentials).

**1. Clear the cache**

Clear the Gradle cache as described in the [Remove Gradle caches](#step-1-remove-gradle-caches) section.

**2. Create the example project**

Create a project directory and navigate to it:

```bash
mkdir gradle-example && cd $_
gradle init --type java-application --dsl groovy \
  --project-name gradle-example \
  --package com.example \
  --no-incubating \
  --no-split-project
```

**3. Edit app/build.gradle**

Open `app/build.gradle` in a text editor. For example, to open it in `nano`:

```bash
nano app/build.gradle
```

Edit the `repositories` block in `app/build.gradle` to point to Chainguard and use the environment variables for your pull token credentials:

```app/build.gradle
repositories {
    maven {
        url = 'https://libraries.cgr.dev/java/'
        credentials {
            username = providers.environmentVariable("CHAINGUARD_JAVA_IDENTITY_ID").orNull
            password = providers.environmentVariable("CHAINGUARD_JAVA_TOKEN").orNull
        }
    }
    mavenCentral()
}
```

If you are using Chainguard's remediated repository for Java libraries, make sure to add `https://libraries.cgr.dev/java-remediated/` first, as shown in the [direct access example](#direct-access-to-chainguard-libraries) earlier in the Gradle section on this page.

**4. Build the project**

Run the following command:

```bash
./gradlew app:assemble
```

The project generated in this example includes `com.google.guava:guava` as a dependency via the
version catalog in `gradle/libs.versions.toml`, so guava is downloaded from
Chainguard Libraries as part of the build.

Following the build, you can find the guava jar declared in the version catalog at:

```
~/.gradle/caches/modules-2/files-2.1/com.google.guava
```

#### Verify the project works as expected

To verify the artifact was built by Chainguard, use `chainctl`. In this example,
we first use `find` to locate the jar:

```bash
find ~/.gradle/caches/modules-2/files-2.1/com.google.guava/guava -name "*.jar" | sort
```

Then copy the exact path to the jar and verify it with `chainctl`:

```bash
chainctl libraries verify /full/path/to/guava-<version>.jar
```

> **Note**: Running `chainctl libraries verify` requires the `libraries.java.pull` permission or the Owner role.

A successfully verified artifact produces output similar to the following:

```bash
Artifact: ~/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/33.5.0-jre/.../guava-33.5.0-jre.jar
Verification Coverage: 100.00%
```

Adjust the repository URL to use your repository manager and add any other
desired packages for further testing.

<a id="bazel"></a>

## Bazel

[Bazel](https://bazel.build/) is a fast, scalable, and extensible build tool
commonly used in large-scale projects.

### Step 1: Remove Bazel caches

Bazel uses a cache to store downloaded artifacts. When adopting Chainguard
Libraries for Java, you must delete this cache to ensure that libraries are
downloaded again. By default, the cache is located in the `.cache/bazel` on
Linux or `/private/var/tmp/_bazel_$USER` on MacOS directory in your user's home
directory. Use the following command to delete it:

```shell
bazel clean --expunge
```

The [Bazel documentation on output
directories](https://bazel.build/remote/output-directories) contains further
details.

### Step 2: Change Bazel configuration

<a name="repo-manager-bazel"></a>

#### Using a repository manager

Before running a new build, you must configure access to Chainguard Libraries
for Java. If the administrator for your organization’s repository manager
created a new repository or virtual repository, you must update your Bazel
configuration to use the repository manager.

Bazel uses `MODULE.bazel` files to define external dependencies as `artifacts`.
You can configure a Maven repository for artifact retrieval using `repositories`
from the
[`rules_jvm_external`](https://github.com/bazel-contrib/rules_jvm_external) rule:

Following is an example configuration for a repository manager:

```MODULE.bazel
bazel_dep(name = "rules_jvm_external", version = "6.3")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

maven.install(
    name = "maven",
    # Example dependencies to retrieve
    artifacts = [
        "com.google.guava:guava:32.0.1-jre",
        "org.slf4j:slf4j-api:2.0.5",
        "ch.qos.logback:logback-classic:1.4.7",
    ],
    repositories = [
        # To use Chainguard Libraries for Java via a repository manager:
        "https://repo.example.com/repository/java-all/",
    ],
    # Uncomment and configure authentication if needed:
    # auth = {
    #     "https://repo.example.com/repository/java-all/": {
    #         "type": "basic",
    #         "username": "YOUR_USERNAME_FOR_REPOSITORY_MANAGER",
    #         "password": "YOUR_PASSWORD",
    #     },
    # },
)

use_repo(maven, "maven")
```

Example URLs for repository managers:

* Cloudsmith: https://dl.cloudsmith.io/basic/exampleorg/java-all/maven/
* JFrog Artifactory: https://example.jfrog.io/artifactory/java-all/
* Sonatype Nexus: https://repo.example.com:8443/repository/java-all/

#### Using direct access

If your organization does not use a repository manager, you can configure the
Chainguard Libraries for Java repository directly, and include the Maven Central
repository as fallback. Replace the placeholders `CHAINGUARD_JAVA_IDENTITY_ID`
and `CHAINGUARD_JAVA_TOKEN` with the credentials provided by Chainguard:

```MODULE.bazel
maven.install(
    name = "maven",
    # Example dependencies to retrieve
    artifacts = [
        "com.google.guava:guava:32.0.1-jre",
        "org.slf4j:slf4j-api:2.0.5",
        "ch.qos.logback:logback-classic:1.4.7",
    ],

    repositories = [
        # To use Chainguard Libraries directly (requires credentials):
        "https://libraries.cgr.dev/java/",

        # Use Maven Central as fallback
        "https://repo1.maven.org/maven2/",
    ],
    auth = {
         "https://libraries.cgr.dev/java/": {
             "type": "basic",
             "username": "CHAINGUARD_JAVA_IDENTITY_ID",
             "password": "CHAINGUARD_JAVA_TOKEN",
         },
    },
)
```

Ensure that the Chainguard repository is listed before any other repositories to
prioritize it for artifact retrieval.

For more complex Bazel setups, you can use [.netrc for
authentication](/chainguard/libraries/introduction/access/#netrc).

Refer to the [official Bazel documentation for
`rules_jvm_external`](https://github.com/bazel-contrib/rules_jvm_external) for
more detailed configuration options.

## Other build tools

Other build tools such as [Apache Ant](https://ant.apache.org/) with the [Maven
Artifact Resolver Ant Tasks](https://maven.apache.org/resolver-ant-tasks/),
[sbt](https://www.scala-sbt.org/), [Leiningen](https://leiningen.org/) and
others use Maven or Gradle caches or similar approaches. Refer to the
documentation of your specific tool and the preceding sections to determine how
to remove any used caches.

These tools also include their own mechanisms to configure repositories for
binary artifact retrieval. Consult the specific documentation and adjust your
configuration to use your repository manager and newly created repository group
or virtual repository.

Example URLs for repository managers:

* Cloudsmith: `https://dl.cloudsmith.io/basic/exampleorg/java-all/maven/`
* JFrog Artifactory: `https://example.jfrog.io/artifactory/java-all/`
* Sonatype Nexus: `https://repo.example.com:8443/repository/java-all/`

## Troubleshooting

### Build fails with "Unknown host invalid" or "nodename nor servname provided"

If your build fails with an error similar to the following, a dependency has been blocked by Chainguard's cooldown policy:

```
Non-resolvable import POM: Could not transfer artifact io.airlift:bom:pom:436
from/to central (https://invalid): invalid: nodename nor servname provided,
or not known
```

The `https://invalid` URL in the error indicates that Chainguard blocked the artifact rather than serving it, and the fallback to Central was also blocked. This happens when a recently published package falls within the cooldown window — a security feature that holds newly published artifacts for a configurable period before serving them, to allow time for malware scanning.

To avoid build failures, you can [disable the cooldown or decrease its length](/chainguard/chainguard-repository/library-policies/#cooldown-policies).

