Managing Maven with JFrog CLI

JFrog Applications and CLI Documentation

 

The JFrog CLI extends the capabilities of the native Maven build tool, enabling seamless integration with Artifactory for dependency resolution and artifact deployment.

When you use jf mvn commands (for example, jf mvn clean install), the CLI acts as an intermediary layer that provides Artifactory-aware capabilities such as:

  • Centralized and consistent authentication

  • Repository-aware dependency resolution

  • Automatic build-info collection

  • Xray security scanning integration

To support different development and CI/CD workflows, the JFrog CLI supports two modes of operation:

  • Wrapped Mode (Default) – Simplifies setup by managing configuration automatically via jf mvn-config

  • Native Mode (Opt-in) – Preserves upstream Maven behavior exactly as-is, including multi-repository resolution from pom.xml

Modes of Operation

In Wrapped Mode, the JFrog CLI actively participates in the Maven workflow. It reads configuration from .jfrog/projects/maven.yaml and injects repository settings into the Maven build process.

Requirements:

  • Run jf mvn-config before first use

  • Configuration file at .jfrog/projects/maven.yaml

Limitation:

The jf mvn-config command supports specifying one repository per resolution type:

  • --repo-resolve-releases

  • --repo-resolve-snapshots

For multi-repository dependency resolution, use Native Mode instead.

In Native Mode, the JFrog CLI executes Maven without injecting configuration. All repository settings must be defined in your pom.xml or settings.xml files.

Key Benefit: Multi-Repository Support

Native Mode enables Maven to resolve dependencies from multiple repositories as defined in your pom.xml, exactly like the standard mvn command. This is ideal for enterprise environments where projects depend on artifacts from multiple internal and external repositories.

Enabling Native Mode:

export JFROG_RUN_NATIVE=true
    

Feature

Wrapped Mode (Default)

Native Mode (Opt-in)

Enabling

Enabled by default

export JFROG_RUN_NATIVE=true

Core Behavior

CLI intercepts and enhances execution

CLI runs Maven unmodified

jf mvn-config

Required

Ignored

CLI YAML (.jfrog/projects/maven.yaml)

Applied

Ignored

Repository Injection

Injects repository configuration

Never injects

Multi-Repository Resolution

Single repository per type

Unlimited repositories from pom.xml

Build-Info Collection

Automatic with build flags

Supported with build flags

Build-Info Source

CLI configuration

Project configuration files

Requires Artifactory "Set Me Up"

Optional

Required

Use Wrapped Mode when you want:

  • Minimal configuration overhead

  • Automated repository injection

  • Simplified onboarding for teams

  • Automatic integration with Artifactory

  • A single virtual repository for dependency resolution

Use Native Mode when you need:

  • Multi-repository dependency resolution

  • Enterprise workflows with separate repositories per dependency source

  • Zero modification to project metadata

  • Fully deterministic builds matching standard mvn behavior

  • All configuration version-controlled in project files

  • Existing Maven settings.xml integration

  • Build-info collection without custom Maven plugin configuration

Command Reference

The jf mvn command triggers the Maven client while resolving dependencies and deploying artifacts from and to Artifactory.

Syntax:

jf mvn <goals and options> [command options]
    

Command Options

Flag

Description

Default

--build-name

Build name for build-info collection (requires --build-number)

None

--build-number

Build number for build-info collection

None

--project

JFrog Project key

None

--deployment-threads

Parallel upload threads

3

--insecure-tls

Skip TLS certificate verification

false

--detailed-summary

Include affected files in summary

false

--scan

Scan artifacts with Xray before upload

false

--format

Scan output format (table, json, simple-json)

table

Configures Maven repositories for Wrapped Mode.

Syntax:

jf mvn-config [command options]
    

Options

Flag

Description

--global

Store configuration globally

--server-id-resolve

Server ID for dependency resolution

--server-id-deploy

Server ID for artifact 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

Artifacts include patterns

--exclude-patterns

Artifacts exclude patterns

--disable-snapshots

Disable snapshot resolution

--snapshots-update-policy

Snapshot update policy

Wrapped Mode Workflow

Step 1: Configure Repositories

jf mvn-config \
  --server-id-resolve=my-server \
  --server-id-deploy=my-server \
  --repo-resolve-releases=libs-release \
  --repo-resolve-snapshots=libs-snapshot \
  --repo-deploy-releases=libs-release-local \
  --repo-deploy-snapshots=libs-snapshot-local
    

Step 2: Run Maven Build

jf mvn clean install \
  --build-name=my-maven-build \
  --build-number=1
    

Step 3: Publish Build-Info

jf rt bp my-maven-build 1
    
Native Mode Workflow

Prerequisites:

1. Configure JFrog CLI authentication:

jf c add my-server \
  --url=https://mycompany.jfrog.io \
  --access-token=my-token
    

2. Configure Maven authentication using Artifactory Set Me Up

Step 1: Enable Native Mode

export JFROG_RUN_NATIVE=true
    

Step 2: Define Multiple Repositories in pom.xml

<project>
  <repositories>
    <repository>
      <id>artifactory-releases</id>
      <url>https://mycompany.jfrog.io/artifactory/libs-release</url>
    </repository>

    <repository>
      <id>artifactory-snapshots</id>
      <url>https://mycompany.jfrog.io/artifactory/libs-snapshot</url>
    </repository>

    <repository>
      <id>corporate-libs</id>
      <url>https://mycompany.jfrog.io/artifactory/corporate-maven</url>
    </repository>

    <repository>
      <id>third-party</id>
      <url>https://mycompany.jfrog.io/artifactory/third-party-maven</url>
    </repository>
  </repositories>

  <distributionManagement>
    <repository>
      <id>artifactory-releases</id>
      <url>https://mycompany.jfrog.io/artifactory/libs-release-local</url>
    </repository>
    <snapshotRepository>
      <id>artifactory-snapshots</id>
      <url>https://mycompany.jfrog.io/artifactory/libs-snapshot-local</url>
    </snapshotRepository>
  </distributionManagement>
</project>
    

Step 3: Configure Authentication in settings.xml

<settings>
  <servers>
    <server>
      <id>artifactory-releases</id>
      <username>${env.ARTIFACTORY_USER}</username>
      <password>${env.ARTIFACTORY_PASSWORD}</password>
    </server>
    <server>
      <id>artifactory-snapshots</id>
      <username>${env.ARTIFACTORY_USER}</username>
      <password>${env.ARTIFACTORY_PASSWORD}</password>
    </server>
    <server>
      <id>corporate-libs</id>
      <username>${env.ARTIFACTORY_USER}</username>
      <password>${env.ARTIFACTORY_PASSWORD}</password>
    </server>
    <server>
      <id>third-party</id>
      <username>${env.ARTIFACTORY_USER}</username>
      <password>${env.ARTIFACTORY_PASSWORD}</password>
    </server>
  </servers>
</settings>
    

Step 4: Run Maven Build with Build-Info

jf mvn clean install \
  --build-name=my-enterprise-build \
  --build-number=${BUILD_NUMBER}
    

Step 5: Publish Build-Info

jf rt bp my-enterprise-build ${BUILD_NUMBER}
    
Examples

GitHub Actions Example (Native Mode)

name: Maven Build with JFrog CLI (Native Mode)

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - uses: jfrog/setup-jfrog-cli@v4
        env:
          JF_URL: ${{ secrets.JF_URL }}
          JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }}

      - name: Configure Maven settings.xml
        run: |
          mkdir -p ~/.m2
          echo '${{ secrets.MAVEN_SETTINGS_XML }}' > ~/.m2/settings.xml

      - name: Build (Native Mode)
        env:
          JFROG_RUN_NATIVE: 'true'
        run: |
          jf mvn clean install \
            --build-name=my-app \
            --build-number=${{ github.run_number }}

      - name: Publish Build Info
        run: jf rt bp my-app ${{ github.run_number }}
    
Frequently Asked Questions

Q: Why do I still use jf mvn in Native Mode?

A: Native Mode runs Maven unmodified, but the jf prefix is still required for build-info collection and secure credential handling.

Q: Does Native Mode support build-info collection?

A: Yes. Build-info is supported when --build-name and --build-number are provided.

Q: Can I use multiple repositories for dependency resolution?

A: Yes, using Native Mode. Wrapped Mode supports only one repository per type.

Q: How do I publish build-info without Maven plugins?

A: Use Native Mode:

export JFROG_RUN_NATIVE=true
jf mvn clean install --build-name=my-build --build-number=1
jf rt bp my-build 1
    

Q: Is jf mvn-config required in Native Mode?

A: No. It is ignored.

Q: Why does my build fail with "no config file was found"?

A: You are running Wrapped Mode without jf mvn-config. Either configure it or enable Native Mode.

Environment Variables

Variable

Description

JFROG_RUN_NATIVE

Enable Native Mode

JFROG_CLI_RELEASES_REPO

Repository for CLI dependencies

JFROG_CLI_DEPENDENCIES_DIR

Directory for CLI dependencies