Build configuration

Configuring Chainguard Libraries for Java on your workstation
  12 min read

The configuration for the use of Chainguard Libraries depends on your build tools, continuous integration, and continuous deployment setups

At a high level adopting the use of Chainguard Libraries consists of the following steps:

  • Remove local caches on workstations and CI/CD pipelines. This step ensures that any libraries that were already sourced from other repositories are requested again and the version from Chainguard Libraries is used instead of other binaries.
  • Change configuration to access Chainguard Libraries via your repository manager after the changes from the global configuration are implemented.

These changes must be performed on all workstations of individual developers and other engineers running relevant application builds. They must also be performed on any build server such as Jenkins, TeamCity, GitHub or other infrastructure that builds the applications or otherwise downloads and uses relevant libraries.

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 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 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 to determine URL and authentication details.

Direct access

Build configuration to retrieve artifacts directly from the Chainguard Libraries for Java repository at https://libraries.cgr.dev/java/ requires authentication with username and password from a pull token as detailed in access documentation.

Apache Maven

Apache Maven is the most widely used build tool in the Java ecosystem. Dependencies are declared in a pom.xml file and resolved from remote repositories.

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:

rm -rf ~/.m2/repository

Configure access via 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.

<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.

<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:

<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 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. Ensure that the Chainguard repository is located above the necessary override for the built-in central repository and any other repositories.

The following ~/.m2/settings.xml configures direct access with Chainguard as the primary repository and Maven Central as a fallback for transitive dependencies not available from Chainguard. It uses placeholder values CG_PULLTOKEN_USERNAME and CG_PULLTOKEN_PASSWORD or environment variables for the pull token detailed in Chainguard Libraries access:

<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>
      <!-- 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.

Minimal example project

Use the following steps to create a minimal example project for Maven with Chainguard Libraries for Java.

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

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:

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

For testing purposes, you can use direct access and environment variables as detailed in the access documentation.

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

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

Then build the project:

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 inpom.xmlare downloaded to the local Maven repository at ~/.m2/repository. For example, theguava` 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:

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

A successfully verified artifact produces output similar to the following:

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 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 users home directory.

Use the following command to delete it:

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:

repositories {
   ...
    mavenLocal()    
}

If this configuration is used, ensure you delete the local Maven repository as well.

Step 2: Change Gradle configuration

Before running a new build you must configure access to the Chainguard Libraries for Java. 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 using the repositories definition. Each project can also declare repositories separately.

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:

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. The following repositories block demonstrates the recommended method of using environment variables 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:

repositories {
    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:

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.

Step 1: Clear the cache

Clear the Gradle cache as described in the Remove Gradle caches section.

Step 2: Create the example project

Run the following command:

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

Step 3: Edit 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:

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()
}

Step 4: Build the project

Run the following command:

./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, 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:

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:

chainctl libraries verify --parent your-org /full/path/to/guava-<version>.jar

A successfully verified artifact produces output similar to the following:

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.

Bazel

Bazel is a fast, scalable, and extensible build tool commonly used in large-scale projects.

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:

bazel clean --expunge

The Bazel documentation on output directories contains further details.

Change Bazel configuration

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 rule:

Following is an example configuration for a repository manager:

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/

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:

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.

Refer to the official Bazel documentation for rules_jvm_external for more detailed configuration options.

Other build tools

Other build tools such as Apache Ant with the Maven Artifact Resolver Ant Tasks, sbt, Leiningen 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/

Last updated: 2025-04-21 13:22