Artifactory Gradle Plugin
Introduction
The Artifactory Gradle Plugin deploys your Gradle build artifacts and publishes build information to JFrog Artifactory so you can trace what your build produced.
Who this is for: Gradle application and library developers who configure publishing in the build itself. If your CI already runs JFrog CLI (for example, the Jenkins JFrog Plugin or Setup JFrog CLI on GitHub Actions), see When to use this plugin.
The plugin adds three Gradle tasks.
| Task | Scope | Purpose |
|---|---|---|
artifactoryPublish | Per project | Collects deploy details from publications. |
extractModuleInfo | Per project | Produces moduleInfo.json from collected details. |
artifactoryDeploy | Root project only | Deploys artifacts and build information to JFrog Artifactory. |
Execution flow: artifactoryPublish then extractModuleInfo then artifactoryDeploy (root).
- Plugin ID:
com.jfrog.artifactory - Supported Gradle: The minimum version enforced by code is 6.8.1. Gradle 8 or above is recommended. The plugin is primarily tested with Gradle 9+.
- Java: The plugin compiles to Java 8. Gradle 9 itself requires Java 17 or later.
When to use this plugin
Recommended path
- Use this plugin when you want Artifactory publishing configured in your Gradle build (local builds or any CI that runs Gradle with this plugin applied).
- Prefer JFrog CLI (
jf gradleor upload and build-publish commands) when your CI is already CLI-first — for example Jenkins JFrog Plugin or GitHub Actions Setup JFrog CLI.- Versions: Gradle 9 or later → plugin 6.x. Gradle 6.8.1 through 8 → plugin 5.x. Do not start new work on plugin 4.x — see Migration and Compatibility.
Prerequisites
Before you configure the plugin, ensure the following:
- Gradle 6.8.1 or later. If your Gradle version is lower, the build fails with a message that states the minimum supported version.
- A JDK that satisfies your Gradle version. Gradle 9 requires Java 17 or later.
- A JFrog Artifactory instance with a Maven or Gradle local repository you can deploy to.
- Publisher credentials: a username with password, or a username with an access token where your platform allows token authentication. Store secrets in
gradle.propertiesor CI secrets — not in source control. - The
maven-publishplugin, theivy-publishplugin, or both, applied to every project you want to publish, and at least one publication defined. The Artifactory plugin collects artifacts from Gradle publications. It doesn't create them.
Quick Start
A working configuration has two parts: a Gradle publication, and the artifactory block that tells the plugin where to deploy it.
The artifactory block requires contextUrl, repository.repoKey, repository.username, and repository.password.
Configuring only the
artifactoryblock isn't enough. If no publishing plugin is applied, the build fails withExtension of type 'PublishingExtension' does not exist. Applymaven-publishorivy-publishand define at least one publication.
Kotlin:
plugins {
id("java")
id("maven-publish")
id("com.jfrog.artifactory") version "6.+"
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"])
}
}
}
configure<ArtifactoryPluginConvention> {
publish {
contextUrl = "https://acme.jfrog.io/artifactory"
repository {
repoKey = "libs-snapshot-local"
username = project.property("artifactory_user") as String
password = project.property("artifactory_password") as String
}
defaults {
publications("ALL_PUBLICATIONS")
}
}
}Groovy:
plugins {
id 'java'
id 'maven-publish'
id "com.jfrog.artifactory" version "6.+"
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
artifactory {
publish {
contextUrl = 'https://acme.jfrog.io/artifactory'
repository {
repoKey = 'libs-snapshot-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
}
defaults {
publications('ALL_PUBLICATIONS')
}
}
}Store artifactory_user and artifactory_password in gradle.properties or supply them as environment variables rather than hardcoding them in the build script.
To deploy, run the following command. Use the Gradle wrapper if your project has one, or a locally installed gradle.
./gradlew artifactoryPublishThe build runs artifactoryPublish, extractModuleInfo, and artifactoryDeploy, then reports the deployed artifacts and the published build information.
> Task :artifactoryPublish
> Task :extractModuleInfo
[pool-1-thread-1] Deploying artifact: https://acme.jfrog.io/artifactory/libs-snapshot-local/org/example/my-app/1.0.0/my-app-1.0.0.jar
[pool-1-thread-1] Deploying artifact: https://acme.jfrog.io/artifactory/libs-snapshot-local/org/example/my-app/1.0.0/my-app-1.0.0.module
[pool-1-thread-1] Deploying artifact: https://acme.jfrog.io/artifactory/libs-snapshot-local/org/example/my-app/1.0.0/my-app-1.0.0.pom
> Task :artifactoryDeploy
Deploying build info...
Build-info successfully deployed.
BUILD SUCCESSFUL
Outside a CI environment the build also prints
No build-info config properties file path provided.This line is informational. The plugin reads that file only in CI init-script mode, and build information is still published without it.
Multi-project setup
Apply the plugin with apply false in the root build script, then apply it in allprojects or selected subprojects. The plugin auto-applies itself to the root project when you apply it to a subproject. It isn't applied to buildSrc.
Kotlin:
plugins {
id("com.jfrog.artifactory") apply false
}
allprojects {
apply(plugin = "com.jfrog.artifactory")
}Groovy:
plugins {
id 'com.jfrog.artifactory' apply false
}
allprojects {
apply plugin: 'com.jfrog.artifactory'
}What you should see next
After a successful artifactoryPublish, confirm both the artifacts and the build information.
- In the Gradle log, note the deployed artifact URLs and the build name and number (by default, the root project name and an epoch-millisecond timestamp).
- In the JFrog Platform UI, open Builds, then open that build name and number to view modules, artifacts, and dependencies.
- Optionally verify with JFrog CLI (if configured):
jf rt curl -s -XGET /api/build/<build-name>For more on reading builds in Artifactory, see Inspect Builds, Manage Builds, and About Build Info.
Configuration Reference
Top-Level artifactory Block
The following table describes the top-level properties you can configure in the artifactory block.
| Block or Property | Purpose | Default |
|---|---|---|
publish { } | Publishing configuration. | -- |
buildInfo { } | Build information metadata. | -- |
proxy { } | HTTP proxy settings. | -- |
clientConfig.timeout | Connection timeout in seconds. | -- |
clientConfig.connectionRetries | Number of connection retries. | -- |
clientConfig.insecureTls | Skip TLS certificate verification. | false |
clientConfig.isIncludeEnvVars | Include environment variables in build information. | false |
clientConfig.envVarsIncludePatterns | Comma-separated include patterns for environment variables. | -- |
clientConfig.envVarsExcludePatterns | Comma-separated exclude patterns for environment variables. | -- |
clientConfig.timeout and clientConfig.connectionRetries have no plugin-level default. When you don't set them, the underlying HTTP client determines the effective value.
Kotlin:
configure<ArtifactoryPluginConvention> {
publish { /* ... */ }
buildInfo { /* ... */ }
proxy { /* ... */ }
clientConfig.timeout = 600
clientConfig.connectionRetries = 4
clientConfig.insecureTls = false
clientConfig.isIncludeEnvVars = true
clientConfig.envVarsExcludePatterns = "*password*,*secret*"
clientConfig.envVarsIncludePatterns = "*not-secret*"
}Groovy:
artifactory {
publish { /* ... */ }
buildInfo { /* ... */ }
proxy { /* ... */ }
clientConfig.timeout = 600
clientConfig.setConnectionRetries(4)
clientConfig.setInsecureTls(false)
clientConfig.setIncludeEnvVars(true)
clientConfig.setEnvVarsExcludePatterns('*password*,*secret*')
clientConfig.setEnvVarsIncludePatterns('*not-secret*')
}publish Block
The following table describes the properties available in the publish block.
| Property | Purpose | Default |
|---|---|---|
contextUrl | JFrog Artifactory base URL. | -- |
repository { } | Target repository settings. | -- |
repository.repoKey | Single repository key. | -- |
repository.releaseRepoKey | Release repository key. | -- |
repository.snapshotRepoKey | Snapshot repository key. | -- |
repository.username | Publisher username. | -- |
repository.password | Publisher password. | -- |
repository.ivy { } | Ivy layout configuration (when publishIvy = true). | -- |
repository.ivy.ivyLayout | Ivy descriptor layout pattern. Setting it enables Ivy publishing. | -- |
repository.ivy.artifactLayout | Ivy artifact layout pattern. | -- |
repository.ivy.mavenCompatible | Convert dots to path separators in [organization]. | true |
defaults { } | Default configuration applied to all artifactoryPublish tasks. | -- |
publishBuildInfo | Publish build information to JFrog Artifactory. | true |
forkCount | Number of parallel deploy threads. | 3 |
Kotlin:
publish {
contextUrl = "https://acme.jfrog.io/artifactory"
repository {
repoKey = "libs-snapshot-local"
// Or use release and snapshot repositories:
// releaseRepoKey = "libs-release-local"
// snapshotRepoKey = "libs-snapshot-local"
username = project.property("artifactory_user") as String
password = project.property("artifactory_password") as String
ivy {
ivyLayout = "[organization]/[module]/ivy-[revision].xml"
artifactLayout = "[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]"
mavenCompatible = true
}
}
defaults {
publications("mavenJava", "ivyJava")
}
publishBuildInfo = true
forkCount = 5
}Groovy:
publish {
contextUrl = 'https://acme.jfrog.io/artifactory'
repository {
repoKey = 'libs-snapshot-local'
username = "${artifactory_user}"
password = "${artifactory_password}"
ivy {
ivyLayout = '[organization]/[module]/ivy-[revision].xml'
artifactLayout = '[organization]/[module]/[revision]/[module]-[revision](-[classifier]).[ext]'
mavenCompatible = true
}
}
defaults {
publications('mavenJava', 'ivyJava')
}
publishBuildInfo = true
forkCount = 5
}buildInfo Block
The following table describes the properties available in the buildInfo block.
| Property | Purpose |
|---|---|
buildName | Override build name. Default is the root project name. |
buildNumber | Override build number. Default is an epoch-millisecond timestamp. |
project | JFrog Artifactory project key. |
addEnvironmentProperty(key, value) | Add a custom environment property. |
generatedBuildInfoFilePath | Path for an extra build information JSON copy. |
deployableArtifactsFilePath | Path for deployed artifacts JSON. |
Kotlin:
buildInfo {
buildName = "my-build"
buildNumber = "" + Random(System.currentTimeMillis()).nextInt(20000)
project = "project-key"
addEnvironmentProperty("test.adding.dynVar", Date().toString())
generatedBuildInfoFilePath = "/path/to/myBuildInfoCopy.json"
deployableArtifactsFilePath = "/path/to/myArtifactsInBuild.json"
}Groovy:
buildInfo {
setBuildName('my-build')
setBuildNumber('' + new Random(System.currentTimeMillis()).nextInt(20000))
setProject('project-key')
addEnvironmentProperty('test.adding.dynVar', new java.util.Date().toString())
setGeneratedBuildInfoFilePath('/path/to/myBuildInfoCopy.json')
setDeployableArtifactsFilePath('/path/to/myArtifactsInBuild.json')
}You can also control build name and number through gradle.properties.
buildInfo.build.name=my-super-cool-build
buildInfo.build.number=r9001proxy Block
The following table describes the properties available in the proxy block.
| Property | Purpose |
|---|---|
host | Proxy hostname. |
port | Proxy port. |
username | Proxy username. |
password | Proxy password. |
noProxy | Hosts to bypass the proxy. |
proxy {
host = 'www.somehost.org'
port = 8080
username = 'userid'
password = 'password'
noProxy = 'internal.myorg.com'
}For dependency resolution through a proxy, use the standard Gradle proxy configuration in gradle.properties.
systemProp.http.proxyHost=www.somehost.org
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=userid
systemProp.http.proxyPassword=passwordartifactoryPublish Task and defaults Block
The defaults block inside publish applies configuration to every artifactoryPublish task. You can also configure a specific project's task directly.
The following table describes the properties available on the task or in the defaults block.
| Property | Purpose | Default |
|---|---|---|
publications(...) | Publications to include. | -- |
publications("ALL_PUBLICATIONS") | Include all known publications. | -- |
properties | Map of artifact properties. | -- |
properties { configName artifactSpec, key:val } | Scoped properties (Groovy closure). | -- |
skip | Skip this project entirely. | false |
publishArtifacts | Publish artifacts. | true |
publishPom | Publish POM files. | true |
publishIvy | Publish Ivy descriptors. | true |
moduleType | Module type in build information. | GRADLE |
The following moduleType values are valid: GENERIC, MAVEN, GRADLE, IVY, DOCKER, NUGET, NPM, GO, PYPI, CPP, and BUILD.
When a CI server supplies publisher configuration through a build-info.properties file, that configuration takes precedence over publishPom and publishIvy values set in the build script.
Kotlin (per-project task):
tasks.named<ArtifactoryTask>("artifactoryPublish") {
publications(
publishing.publications["ivyJava"],
"mavenJava",
"ALL_PUBLICATIONS"
)
setProperties(mapOf("key1" to "value1", "key2" to "value2"))
skip = false
setPublishArtifacts(true)
setPublishPom(true)
setPublishIvy(true)
setModuleType("GRADLE")
}Groovy (per-project task):
artifactoryPublish {
publications('ALL_PUBLICATIONS')
properties = ['qa.level': 'basic', 'dev.team': 'core']
properties {
simpleFile '**:**:**:*@*', simpleFile: 'only on settings file'
}
skip = false
publishArtifacts = true
publishPom = true
publishIvy = true
moduleType = 'GRADLE'
}Artifact notation for scoped properties: group:module:version:classifier@type (for example, org.example:my-artifact:1.0.0:test@jar). Wildcards: * for any characters, ? for a single character. Use all as the configuration name to apply to all publications or configurations.
Publications
ALL_PUBLICATIONS
Set publications("ALL_PUBLICATIONS") to publish artifacts from every publication defined in the project.
Default Publications
When you don't specify any publications and the project has the publishing extension applied, the plugin automatically looks for mavenJava, mavenJavaPlatform, mavenWeb, and ivyJava.
Maven and Ivy Side by Side
The following example shows how to configure both Maven and Ivy publications in the same project.
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
ivyJava(IvyPublication) {
from components.java
}
}
}
artifactory {
publish {
defaults {
publications('mavenJava', 'ivyJava')
}
}
}Artifact Properties
Simple Map
artifactoryPublish {
properties = ['qa.level': 'basic', 'q.os': 'win32, deb, osx']
}Scoped Properties (Groovy Closure)
artifactoryPublish {
properties {
foo '*:*:*:*@*', platform: 'linux', 'win64'
mavenJava 'org.jfrog:*:*:*@*', key1: 'val1'
all 'org.jfrog:shared:1.?:*@*', key2: 'val2', key3: 'val3'
}
}The syntax follows this format: configName 'group:module:version:classifier@type', key1:'value1', key2:'value2'
configName: A publication name, orallto apply to all publications.- The artifact filter supports
*(any characters) and?(single character).
Use Cases and Examples
The plugin repository includes sample projects that the plugin's own functional tests build. Use them as reference configurations.
| Use Case | Example Project | Notes |
|---|---|---|
| Multi-module Maven + Ivy (Groovy) | gradle-example-publish | Uses mavenJava and ivyJava publications. |
| Multi-module (Kotlin DSL) | gradle-kts-example-publish | Same configuration in Kotlin. |
| Android (APK and AAR) | gradle-android-example | Custom publications per module, and per-project publications(...). |
| Proxy with noProxy bypass | gradle-example-publish/build.gradle | Uses proxy { host, port, noProxy }. |
| Default BOM | gradle-example-default-bom | Java Platform (BOM) publishing. |
| Custom BOM | gradle-example-custom-bom | Custom mavenJavaPlatform. |
| Version catalog | gradle-example-version-catalog | Producer and consumer setup. |
| Gradle plugin publishing | gradle-plugin | Uses ALL_PUBLICATIONS. |
| Skip root or specific modules | All examples | Uses artifactoryPublish.skip = true. |
For end-to-end sample projects, see the Gradle examples in the JFrog project-examples repository.
Sub-Project Control
The plugin supports hierarchical configuration. Define artifactory { } in the root project and all subprojects inherit it. Any subproject can override the publish or repository configuration.
Set artifactoryPublish.skip = true on a project to exclude it from publishing.
./gradlew clean api:artifactoryPublish shared:artifactoryPublishCI Integration
If your CI server already installs and configures JFrog CLI — for example the Jenkins JFrog Plugin or Setup JFrog CLI on GitHub Actions — you can publish with CLI commands and may not need this Gradle plugin in the build script.
When CI runs Gradle with this plugin, a CI driver (JFrog CLI or a legacy Jenkins Artifactory Plugin job) may apply the plugin through an init script (initscripttemplate.gradle). That init script does the following:
- Applies
ArtifactoryPluginSettingsto the settings, which adds JFrog Artifactory as a resolution repository. - Applies
ArtifactoryPluginto all projects. - Sets
setCiServerBuild()on everyartifactoryPublishtask to enable CI mode.
In CI mode, publications are read from the ArtifactoryClientConfiguration.publisher.publications property, which is populated from build-info.properties generated by JFrog CLI or the CI integration.
Resolver from Properties
When a build-info.properties file is present (set through the BUILDINFO_PROPFILE or PROP_PROPS_FILE environment variable), the plugin reads contextUrl and repoKey from it and configures JFrog Artifactory as the resolution repository, replacing other remote Maven and Ivy repositories.
Migration and Compatibility
Version 6 (Current)
Version 6 of the Gradle Artifactory Plugin introduces support for Gradle version 9. The code and documentation for Version 6 are available at the Gradle Artifactory Plugin GitHub repository.
Note: For Gradle version 6.8.1 through 8 (inclusive), use version 5. For Gradle 9, use version 6.
Version 6 includes the following breaking changes:
- The plugin compiles to Java 8. Gradle 9 itself requires Java 17 or later.
- The minimum Gradle version enforced by the plugin is 6.8.1. Gradle 8 or above is recommended. The plugin is primarily tested with Gradle 9+.
- The web-archive convention attribute has been removed. The plugin now produces both JAR and WAR archives.
Version 5
This major release completely rewrote the plugin code from Groovy to Java.
Version 5 includes the following breaking changes:
- The minimum supported Gradle version has been increased to 6.8.1. The legacy archive configurations are no longer supported.
- The
parentclosure in theartifactoryconvention is no longer compatible or supported.
Migrate from Version 4 to Version 5 or 6
The following Version 4 features have been removed or relocated.
| Version 4 Feature | Status in Version 5 and 6 |
|---|---|
publishConfigs() | Removed. Use publications() instead. |
mavenDescriptor | Removed. |
ivyDescriptor | Removed. |
publishBuildInfo in defaults | Moved to publish { publishBuildInfo = ... }. |
contextUrl on artifactoryPublish task | Removed from task. Set on publish { contextUrl = ... }. |
clientConfig.publisher.* on task | Removed from task. Set on artifactory { publish { repository { ... } } }. |
clientConfig.proxy.* | Replaced with proxy { } closure. |
clientConfig.info.* | Replaced with buildInfo { } closure. |
parent closure | Removed. |
Troubleshooting
The following table describes common problems and their solutions.
| Problem | Solution |
|---|---|
Build fails with Extension of type 'PublishingExtension' does not exist. | Apply the maven-publish plugin, the ivy-publish plugin, or both, and define at least one publication. The Artifactory plugin collects artifacts from Gradle publications and doesn't create them. |
| Build fails with a Gradle version error. | The plugin requires Gradle 6.8.1 or later. Update Gradle or use an older plugin version. The error message includes the minimum supported version. |
| Deploy fails with 401 or 403. | Confirm the user or token can deploy to the target repository and publish build information. Store credentials in gradle.properties or CI secrets — not in source control. An access token can be used as the password where your platform allows it. |
| Artifacts deploy but you can't find the build under your Artifactory Project. | Set buildInfo { project = "your-project-key" } (or the matching property) and confirm the Project exists. |
| Wrong repository or empty deploy. | Use a Maven or Gradle local repository key. Match snapshot versus release repositories (repoKey versus releaseRepoKey / snapshotRepoKey) to your version scheme. |
| Build log shows success but you don't know where to look. | Open Builds in the JFrog Platform UI and open the build name printed in the log, or run jf rt curl -s -XGET /api/build/<build-name> with a configured CLI. |
| No artifacts published. | Verify that publications() is configured and the named publications exist in the project. |
The build prints No build-info config properties file path provided. | This message is informational. The plugin looks for a CI-supplied build-info.properties file and continues without it. Build information is still published. |
| Invalid properties specification error. | Use the format configName 'group:module:version:classifier@type', key1:'value1', key2:'value2'. |
| You need detailed logs. | Run Gradle with -d for debug output. |
| Proxy doesn't work for deployment. | Configure the proxy { } block inside artifactory { }. |
| Proxy doesn't work for resolution. | Proxy for dependency resolution uses the standard Gradle configuration in gradle.properties (systemProp.http.proxyHost and related properties). The plugin doesn't intervene in resolution. |
Related topics
- About Build Info
- Inspect Builds
- Manage Builds
- Maven Artifactory Plugin
- GitHub Actions
- Jenkins JFrog Plugin
- Gradle examples in project-examples
Legacy: Gradle Artifactory Plugin Version 4
Do not start new projects on Version 4. Migrate to Version 5 or 6 using the table in Migrate from Version 4 to Version 5 or 6.
Version 4 used a different Convention DSL (publishConfigs, task-level contextUrl, clientConfig.publisher.*, and related APIs). Those features are removed or relocated in Version 5 and 6. For historical Version 4 examples, see older tags in the artifactory-gradle-plugin repository and the migrate table above.
Updated 15 days ago
