Use Gradle with JFrog CLI

Run Gradle builds with Artifactory integration for dependency resolution and build information collection.

This topic covers the following tasks:

When to Use

Use jf gradle if your Java/Kotlin project uses Gradle (build.gradle or build.gradle.kts) for builds and you want dependencies resolved from Artifactory with build-info collection. For Maven-based projects, use jf mvn.

Prerequisites

  • Gradle 6.0+ installed and available on $PATH (verify with gradle --version or ./gradlew --version). On macOS: brew install gradle. On Linux: see gradle.org/install.
  • Java Development Kit (JDK) 11+ installed (verify with java -version). On macOS: brew install openjdk. On Linux: install via your package manager or Adoptium.
  • Run jf gradle-config in the project directory before the first build.
  • Configure a server with jf config add or jf c add.
  • Authentication to Artifactory is required.

Configuration: jf gradle-config

Generate Gradle build configuration for resolving and deploying artifacts through Artifactory. Run this once per project before your first build.

To configure Gradle for Artifactory:

Synopsis

jf gradle-config [options]

Aliases: gradlec

Configuration Options

FlagDefaultDescription
--globalfalseApply configuration globally for all projects
--server-id-resolveArtifactory server ID for dependency resolution
--server-id-deployArtifactory server ID for deployment
--repo-resolveRepository for resolving dependencies
--repo-deployRepository for deploying artifacts
--uses-pluginfalseSet to true if the Gradle Artifactory Plugin is already applied
--use-wrapperfalseUse the Gradle wrapper
--deploy-maven-desctrueDeploy Maven descriptors
--deploy-ivy-desctrueDeploy Ivy descriptors
--ivy-desc-pattern[organization]/[module]/ivy-[revision].xmlDeployment pattern for Ivy descriptors
--ivy-artifacts-pattern[organization]/[module]/[revision]/[artifact]-[revision](/docs/-[classifier]).[ext]Deployment pattern for Ivy artifacts

Configuration Examples

View Help

jf gradle-config --help

Non-Interactive Configuration

Configure Gradle with non-interactive flags:

jf gradle-config --server-id-resolve=<server-id> --repo-resolve=<repo-name> --server-id-deploy=<server-id> --repo-deploy=<repo-name>

Where:

  • <server-id>: The server ID configured using jf config add
  • <repo-name>: The name of the repository in Artifactory

For example:

jf gradle-config --server-id-resolve=my-server --repo-resolve=gradle-virtual --server-id-deploy=my-server --repo-deploy=gradle-local

Why Run Config First?

You must run jf gradle-config before jf gradle. The config command creates a .jfrog/projects/gradle.yaml file that tells the CLI which Artifactory repositories to resolve from and deploy to. Without it, jf gradle cannot integrate with Artifactory.

If you skip this step, you will see the error: no config file was found! Before running the 'jf gradle' command on a project for the first time, the project should be configured with the 'jf gradle-config' command.

👍

Shortcut

: In CI/CD, pass all flags non-interactively so the config step is fully automated and reproducible.

📘

Note

: Running jf gradle-config without flags in a non-TTY environment (CI/CD pipelines, piped shell commands) will cause the CLI to crash with a runtime panic (panic: device not configured). Always pass all required flags non-interactively in automated environments.

Configuration Notes

  • Run once per project: Configuration persists in .jfrog/projects/. Re-run when changing repository assignments. Run this command from the root of your Gradle project (the directory containing build.gradle or build.gradle.kts) — the CLI does not validate that a Gradle project exists and will create the config in any directory.
  • Global vs project: Use --global for all Gradle projects on the machine. Without it, configuration is project-specific. The global config is stored at ~/.jfrog/projects/gradle.yaml (macOS/Linux) or %USERPROFILE%\.jfrog\projects\gradle.yaml (Windows).
  • Artifactory Plugin: If your build.gradle already applies the Gradle Artifactory Plugin, set --uses-plugin=true to avoid conflicts.
  • Wrapper support: Use --use-wrapper=true if your project uses the Gradle wrapper (gradlew).
  • Ivy descriptors: The --deploy-ivy-desc and --ivy-desc-pattern flags control Ivy descriptor deployment. Most modern projects use Maven descriptors (--deploy-maven-desc).

Expected Output

$ jf gradle-config --server-id-resolve=my-server --repo-resolve=gradle-virtual --server-id-deploy=my-server --repo-deploy=gradle-local
[Info] gradle build config successfully created.

How to Verify

After running, confirm the configuration exists:

cat .jfrog/projects/gradle.yaml

A correctly generated file looks like this:

version: 1
type: gradle
resolver:
    repo: gradle-virtual
    serverId: my-server
deployer:
    repo: gradle-local
    serverId: my-server
    deployMavenDescriptors: true
    deployIvyDescriptors: true
    ivyPattern: '[organization]/[module]/ivy-[revision].xml'
    artifactPattern: '[organization]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]'

Build: jf gradle

Run Gradle build with Artifactory integration for dependency resolution and build information collection.

To run a Gradle build with Artifactory integration:

Synopsis

jf gradle <tasks-and-options> [options]

Aliases: none

Arguments

ArgumentRequiredDescription
tasks-and-optionsYesGradle tasks and options (for example, build, -b path/to/build.gradle)

Build Options

FlagDefaultDescription
--build-nameBuild name for build information (requires --build-number)
--build-numberBuild number for build information (requires --build-name)
--projectJFrog Artifactory project key
--moduleOptional module name for build information
--detailed-summaryfalseInclude affected files in the command summary
--threads3Number of threads for uploading build artifacts
--server-idServer ID configured with jf config add
--scanfalseScan all files with Xray on the local file system before upload; skip upload if vulnerabilities are found
--formattableOutput format for the --scan option. Accepts table, json, simple-json, or sarif

Build Examples

Build and Publish Build Information

jf gradle build --build-name=<build-name> --build-number=<build-number>

Where:

  • <build-name>: A name for the build (for example, my-java-app)
  • <build-number>: A number or identifier for the build run (for example, 1)

For example:

jf gradle build --build-name=my-java-app --build-number=1

Build with Custom Threads

jf gradle clean build --build-name=my-app --build-number=1 --threads=5

Expected Output

A successful build prints the Gradle task output followed by a summary of uploaded artifacts:

[Info] Running gradle...
...
BUILD SUCCESSFUL in Xs
[Info] Deploying artifact: https://<server>/artifactory/<repo>/<path>/<artifact>.jar
[Info] Deploying artifact: https://<server>/artifactory/<repo>/<path>/<artifact>.pom
[Info] Build info successfully collected. To publish the build info to Artifactory, run:
jf rt build-publish <build-name> <build-number>

If no artifacts were deployed, see Selecting Publications for Gradle.


Important Notes

  • Build-info publishing: Using --build-name and --build-number only collects build info. Publish with jf rt build-publish <name> <number> (jf rt is the legacy Artifactory namespace; the command works in all current CLI versions).
  • Gradle tasks: All standard Gradle tasks and flags work (clean, build, test, -x, -b, and others).
  • Artifactory Plugin: If your build.gradle already applies the Gradle Artifactory Plugin, set --uses-plugin in jf gradle-config to avoid conflicts.
  • Hidden flag — --module: The --module flag is functional and collected by the build-info framework, but does not appear in jf gradle --help output. It works when passed on the command line alongside --build-name and --build-number.

Selecting Publications for Gradle

If you run jf gradle clean artifactoryPublish and the build succeeds but no artifacts are deployed, the Artifactory Gradle plugin likely does not know which publication(s) to publish.

To specify publications for the Artifactory Gradle plugin:

  • Option 1 — gradle.properties

    artifactory.publish.publications=release
    # Or multiple:
    # artifactory.publish.publications=release,debug
  • Option 2 — Command line project property

    jf gradle clean artifactoryPublish \
      -Partifactory.publish.publications=release \
      --build-name="MyApplicationAndroidBuild" \
      --build-number="1" \
      --project="test"
  • Option 3 — In your build script

    // build.gradle.kts
    extra["artifactory.publish.publications"] = "release"
    
    // build.gradle (Groovy)
    // ext["artifactory.publish.publications"] = "release"

These options work because jf gradle passes flags/properties through to the Gradle client, and the Artifactory Gradle plugin's artifactoryPublish task publishes the specified publication(s).

Verify that the publication (for example, release) actually exists in your Gradle publishing block and that your Android/Gradle setup creates a Maven Publication for it.

Native Mode

Gradle supports Native Mode, which bypasses jf gradle-config and all .jfrog/ YAML configuration. In this mode, no Artifactory Gradle plugin is injected — you must configure Gradle to resolve from Artifactory manually. Pass --server-id to specify the server. Build-info is still collected when --build-name and --build-number are provided.

Enable with: export JFROG_RUN_NATIVE=true

For full setup instructions, per-tool comparison, and when to use each mode, see Native Mode.

Platform Notes

  • Windows: The Gradle init script is written to %USERPROFILE%\.gradle\init.d\. If JAVA_HOME is set, the script uses Java's user.home property, which may differ from %USERPROFILE%.
  • Gradle wrapper: On Unix, ensure gradlew has execute permissions (chmod +x gradlew). On Windows, use gradlew.bat automatically.

Environment Variables

VariableDefaultDescription
JFROG_CLI_RELEASES_REPOConfigured Artifactory repository name from which to download the JAR needed by the gradle command. Format: <server ID>/<repo name>. The repository should proxy https://releases.jfrog.io.
JFROG_CLI_DEPENDENCIES_DIR$JFROG_CLI_HOME_DIR/dependenciesDirectory to which JFrog CLI's internal dependencies are downloaded.
JFROG_CLI_EXTRACTORS_REMOTEAlternative to JFROG_CLI_RELEASES_REPO for offline environments. Format: <server ID>/<repo name>. Note: this variable does not appear in jf gradle --help output but is fully functional.

Downloading the Maven and Gradle Extractor JARs

For integration with Maven and Gradle, JFrog CLI uses build-info-extractor JAR files. These JARs are downloaded by JFrog CLI from JFrog's distribution (releases.jfrog.io) the first time they are needed.

Air-gapped or offline? See Air-Gapped and Offline Setup for a step-by-step guide.

To download extractors through an Artifactory remote repository:

  1. Create a remote Maven repository in Artifactory and name it extractors. Configure it to proxy https://releases.jfrog.io/artifactory/oss-release-local.
  2. Verify that this Artifactory server is configured in JFrog CLI using jf c show.
  3. Set the JFROG_CLI_EXTRACTORS_REMOTE environment variable. The value should be the Server ID followed by a slash and the repository name. For example: my-rt-server/extractors.

CI/CD Example (GitHub Actions)

# .github/workflows/build.yml
steps:
  - uses: actions/checkout@v4
  - name: Setup JFrog CLI
    uses: jfrog/setup-jfrog-cli@v4
    env:
      JF_URL: ${{ vars.JF_URL }}
      JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}
  - name: Configure Gradle
    run: jf gradle-config --server-id-resolve=setup-jfrog-cli-server --repo-resolve=gradle-virtual --server-id-deploy=setup-jfrog-cli-server --repo-deploy=gradle-local
  - name: Build with Gradle
    run: jf gradle clean build --build-name=my-java-app --build-number=${{ github.run_number }}
  - name: Publish build info
    run: jf rt build-publish my-java-app ${{ github.run_number }}

Troubleshooting

SymptomCauseFix
no config file was foundjf gradle-config was not runRun jf gradle-config in the project directory
404 on dependency resolutionResolution repository does not exist or name is wrongVerify --repo-resolve matches an existing Artifactory repository
401 / 403 errorsInvalid credentials or insufficient permissionsRe-run jf config add with a valid access token
Build succeeds but no artifacts deployedArtifactory Gradle plugin does not know which publication(s) to publishSet artifactory.publish.publications=release in gradle.properties or via -P flag
Conflict with existing Artifactory Gradle pluginPlugin applied twiceSet --uses-plugin=true in jf gradle-config
Extractor JAR download failsNo internet access on build machineSet JFROG_CLI_EXTRACTORS_REMOTE to an Artifactory remote repo proxying releases.jfrog.io
Gradle wrapper not usedWrapper not enabled in configSet --use-wrapper=true in jf gradle-config
[Warn] couldn't extract payload from Access Token (appears twice per run)Server uses a reference (non-JWT) access tokenInformational only — the build proceeds normally. The warning printing twice per invocation is expected behavior. If basic auth is required, add a username via jf config edit

Enable debug logging: export JFROG_CLI_LOG_LEVEL=DEBUG


Related Topics