Use Maven with JFrog CLI
Run Maven builds with Artifactory integration for dependency resolution and build information collection.
This topic covers the following tasks:
When to Use
Use jf mvn if your Java project uses Apache Maven (pom.xml) for builds and you want dependencies resolved from Artifactory with build-info collection. For Gradle-based projects, use jf gradle.
Running jf mvn instead of native mvn provides:
- Artifactory dependency resolution: Dependencies are fetched from your Artifactory Maven repositories, caching them for your organization
- Build-info collection: When using
--build-nameand--build-number, the CLI records resolved dependencies and produced artifacts - Xray integration: Build info connects to JFrog Xray for vulnerability scanning of your dependency tree
If you don't need these features, use native mvn pointed at Artifactory via settings.xml.
Prerequisites
- Run
jf mvn-configin the project directory before the first build. - Configure a server with
jf config addorjf c add. - Authentication to Artifactory is required.
- Java must be in your
PATHorJAVA_HOMEmust be set. Thejf mvncommand invokesjavadirectly and does not inherit Maven's own Java path. Verify withjava -versionbefore runningjf mvn. On macOS with Homebrew, addexport JAVA_HOME=$(brew --prefix openjdk)to your shell profile. - If your Artifactory server uses reference tokens (non-JWT), configure a username alongside the token:
jf config add --user=<your-username>. Without a username, Maven's HTTP client cannot authenticate and you will see a[Warn]before every build.
Configuration: jf mvn-config
jf mvn-configGenerate Maven build configuration for resolving and deploying artifacts through Artifactory. Run this once per project before your first build.
To configure Maven for Artifactory:
Synopsis
jf mvn-config [options]
Aliases: mvnc
Configuration Options
| Flag | Default | Description |
|---|---|---|
--global | false | Apply configuration globally for all projects |
--server-id-resolve | — | Artifactory server ID for dependency resolution |
--server-id-deploy | — | Artifactory server ID for deployment |
--repo-resolve-releases | — | Repository for resolving release dependencies |
--repo-resolve-snapshots | — | Repository for resolving snapshot dependencies |
--repo-deploy-releases | — | Repository for deploying release artifacts |
--repo-deploy-snapshots | — | Repository for deploying snapshot artifacts |
--include-patterns | — | Wildcard patterns for artifacts to include (multiple patterns separated by , ) |
--exclude-patterns | — | Wildcard patterns for artifacts to exclude (multiple patterns separated by , ) |
--use-wrapper | false | Use the Maven wrapper |
--disable-snapshots | false | Disable snapshot resolution |
--snapshots-update-policy | daily | Snapshot update policy |
Configuration Examples
View Help
jf mvn-config --helpNon-Interactive Configuration
Configure Maven with non-interactive flags:
jf mvn-config --server-id-resolve=<server-id> --repo-resolve-releases=<repo-name> --repo-resolve-snapshots=<repo-name> --server-id-deploy=<server-id> --repo-deploy-releases=<repo-name> --repo-deploy-snapshots=<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 mvn-config --server-id-resolve=my-server --repo-resolve-releases=libs-release --repo-resolve-snapshots=libs-snapshot --server-id-deploy=my-server --repo-deploy-releases=libs-release-local --repo-deploy-snapshots=libs-snapshot-localWhy Run Config First?
You must run jf mvn-config before running jf mvn. The config command creates a .jfrog/projects/maven.yaml file in your project directory that tells the CLI which Artifactory repositories to use for resolution and deployment. Without it, jf mvn does not know where to fetch or deploy artifacts.
If you skip this step, you will see the error: no config file was found! Before running the 'jf mvn' command on a project for the first time, the project should be configured with the 'jf mvn-config' command.
Shortcut
: In CI/CD, pass all flags non-interactively so the config step is fully automated and reproducible.
Configuration Notes
- Run once per project: The configuration is stored in
.jfrog/projects/maven.yamlin your project directory. You only need to run this once (or when changing repository assignments). - Global vs project: Use
--globalto apply the configuration for all Maven projects on the machine. Without it, the configuration is project-specific. - Snapshot policy:
--snapshots-update-policycontrols how often Maven checks for newer snapshot versions. Values:always,daily(default),interval:N(minutes),never. - Wrapper support: Use
--use-wrapperif your project uses the Maven wrapper (mvnw).
Expected Output
$ jf mvn-config --server-id-resolve=my-server --repo-resolve-releases=libs-release --repo-resolve-snapshots=libs-snapshot --server-id-deploy=my-server --repo-deploy-releases=libs-release-local --repo-deploy-snapshots=libs-snapshot-local
maven build config successfully created.
How to Verify
After running, confirm the configuration exists:
cat .jfrog/projects/maven.yamlBuild: jf mvn
jf mvnRun Maven build with Artifactory integration for dependency resolution and build information collection.
First run
: On the first
jf mvninvocation, the CLI automatically downloads a build-info-extractor JAR (~10–15 seconds) fromreleases.jfrog.io. Subsequent runs use the cached copy. In air-gapped environments, setJFROG_CLI_EXTRACTORS_REMOTEbefore your first build. See Downloading the Maven and Gradle Extractor JARs.
To run a Maven build with Artifactory integration:
Synopsis
jf mvn <goals-and-options> [options]
Aliases: none
Arguments
| Argument | Required | Description |
|---|---|---|
goals-and-options | Yes | Maven goals and options (for example, clean install, -f path/to/pom.xml) |
Build Options
| Flag | Default | Description |
|---|---|---|
--build-name | — | Build name for build information (requires --build-number) |
--build-number | — | Build number for build information (requires --build-name) |
--project | — | JFrog Artifactory project key |
--module | — | Optional module name for build information |
--detailed-summary | false | Include affected files in the command summary |
--threads | 3 | Number of threads for uploading build artifacts |
--insecure-tls | false | Skip TLS certificates verification |
--scan | false | Scan all files with Xray on the local file system before upload; skip upload if vulnerabilities are found |
--format | table | Output format for the --scan option. Accepts table, json, simple-json, or sarif |
Build Examples
Build and Publish Build Information
jf mvn clean install --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 mvn clean install --build-name=my-java-app --build-number=1Build with Custom Threads
jf mvn package --build-name=my-app --build-number=1 --threads=5Note
: If you have deployment repositories configured, you will see a
[Warn]before the build:Deployer repository is configured but Maven goal does not trigger deployment. Only 'install' and 'deploy' goals will deploy artifacts to Artifactory.This is expected —packagedoes not deploy. See Deploying Maven Artifacts for the full goal-to-deploy mapping.
Build Without Deploying Artifacts
jf mvn clean install -Dartifactory.publish.artifacts=falseImportant Notes
- Build-info publishing: Using
--build-nameand--build-numberonly collects build info. To publish it to Artifactory, runjf rt build-publish <name> <number>afterward. - Maven goals: All standard Maven goals and flags work (
clean,install,deploy,-DskipTests,-f, and others). The CLI wraps the native Maven execution. - Thread count: The
--threadsflag controls parallel upload of build artifacts to Artifactory, not Maven's own-Tparallelism. - Hidden flag —
--module: The--moduleflag is functional and collected by the build-info framework, but does not appear injf mvn --helpoutput. It works when passed on the command line alongside--build-nameand--build-number.
Deploying Maven Artifacts
When you run Maven through JFrog CLI (jf mvn), the JFrog Build Info Extractor automatically deploys build artifacts to Artifactory. Unlike standard Maven, where deployment only occurs during the deploy phase, the JFrog CLI integration deploys artifacts at the install phase or later.
| Maven Goal | Deploys to Artifactory? |
|---|---|
validate, compile, test, package | No |
install | Yes |
deploy | Yes |
Preventing Deployment
To run Maven through JFrog CLI without deploying artifacts to Artifactory:
- Add the publish flag — Pass
-Dartifactory.publish.artifacts=falseto your goals/options:
jf mvn clean install -Dartifactory.publish.artifacts=false- Use an earlier goal — Run
jf mvn clean packageinstead ofinstallif you only need to build without deploying. - Omit deployment repositories — When configuring the project with
jf mvn-config, do not specify--repo-deploy-releasesor--repo-deploy-snapshots. If no deployment repositories are configured, artifacts will not be deployed.
Native Mode
Maven supports Native Mode, which bypasses jf mvn-config and all .jfrog/ YAML configuration. In this mode, no settings.xml is injected — you must configure Maven to resolve from Artifactory manually (via Set Me Up). 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.
Performance Notes
- Large multi-module projects: Maven builds with many modules generate significant build-info. The
--threadsflag controls upload parallelism for artifacts, not Maven's own-Tthread count. Use both for maximum performance. - Snapshot resolution frequency: If builds are slow due to snapshot checks, set
--snapshots-update-policy=neverinjf mvn-configduring CI builds where snapshot consistency is guaranteed. - Network bandwidth: Dependency resolution speed depends on the network path to Artifactory. Use a local or regional Artifactory instance for best performance.
Environment Variables
| Variable | Default | Description |
|---|---|---|
JFROG_CLI_RELEASES_REPO | — | Configured Artifactory repository from which to download the build-info-extractor JAR. Format: <server ID>/<repo name>. The repository should proxy https://releases.jfrog.io. Also used by jf gradle and jf audit (for Maven/Gradle projects). |
JFROG_CLI_DEPENDENCIES_DIR | $JFROG_CLI_HOME_DIR/dependencies | Directory to which JFrog CLI's internal dependencies are downloaded. |
JFROG_CLI_EXTRACTORS_REMOTE | — | Alternative to JFROG_CLI_RELEASES_REPO for offline environments. Format: <server ID>/<repo name>. |
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:
- Create a remote Maven repository in Artifactory and name it
extractors. Configure it to proxyhttps://releases.jfrog.io/artifactory/oss-release-local. - Verify that this Artifactory server is configured in JFrog CLI using
jf c show. - Set the
JFROG_CLI_EXTRACTORS_REMOTEenvironment 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 Maven
run: jf mvn-config --server-id-resolve=setup-jfrog-cli-server --repo-resolve-releases=libs-release --repo-resolve-snapshots=libs-snapshot --server-id-deploy=setup-jfrog-cli-server --repo-deploy-releases=libs-release-local --repo-deploy-snapshots=libs-snapshot-local
- name: Build with Maven
run: jf mvn clean install -DskipTests --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
| Symptom | Cause | Fix |
|---|---|---|
no config file was found | jf mvn-config was not run | Run jf mvn-config in the project directory |
| 404 on dependency resolution | Resolution repository does not exist or name is wrong | Verify --repo-resolve-releases and --repo-resolve-snapshots match existing Artifactory repositories |
| 401 / 403 errors | Invalid credentials or insufficient permissions | Re-run jf config add with a valid access token |
[Warn] couldn't extract payload from Access Token... reference token... requires a username | Access token is a reference token (non-JWT). Maven's HTTP client requires basic auth (username + token). | Re-run jf config add --user=<your-username> to add a username to the server config. |
Unable to locate a Java Runtime | JAVA_HOME is not set and java is not in system PATH | Set JAVA_HOME to your JDK installation and export it: export JAVA_HOME=$(brew --prefix openjdk) (macOS Homebrew) or export JAVA_HOME=/usr/lib/jvm/java-21 (Linux). Verify with java -version. |
Artifacts deployed at install phase unexpectedly | JFrog Build Info Extractor deploys at install and later phases | Pass -Dartifactory.publish.artifacts=false or use jf mvn clean package |
| Build-info shows 0 dependencies | --build-name and --build-number not passed to jf mvn | Add both flags to the Maven command |
| Extractor JAR download fails | No internet access on build machine | Set JFROG_CLI_EXTRACTORS_REMOTE to an Artifactory remote repo proxying releases.jfrog.io |
| Snapshot resolution is slow | Default update policy checks daily | Set --snapshots-update-policy=never in jf mvn-config for CI builds |
JVM native-access warnings on every build (WARNING: A restricted method... java.lang.System::load) | Maven's bundled jansi library triggers a restricted native-access warning on Java 21+ | These are Maven warnings, not JFrog CLI errors. Suppress with export MAVEN_OPTS='--enable-native-access=ALL-UNNAMED' in your shell profile. |
Enable debug logging: export JFROG_CLI_LOG_LEVEL=DEBUG
Related Topics
- Build Tools Overview — Capabilities matrix and tool reference
- Native Mode — Supported packages with Native Mode
Updated about 1 month ago
