Gradle resolves module dependencies by looking for metadata files (.module, .pom, or ivy.xml) and a default artifact (usually a JAR). If none of these files are found, the build fails. In some cases, you may need to customize how Gradle resolves artifacts.

Why Use Custom Artifact Resolution?

You might need to tweak artifact resolution in the following scenarios:

  • The dependency provides a non-standard artifact (e.g., a ZIP file) without metadata.

  • The module metadata declares multiple artifacts (e.g., an Ivy dependency descriptor).

  • You want to download only a specific artifact without transitive dependencies.

Step 1: Resolving an Artifact Without Metadata

Let’s say you want to build a web application that uses JavaScript libraries, such as jQuery, and download them from a repository instead of checking them into version control.

Google Hosted Libraries provides open-source JavaScript libraries. Using artifact-only notation, you can fetch a JavaScript file like jquery.js.

The @ character separates the dependency’s coordinates from the artifact’s file extension:

build.gradle.kts
repositories {
    ivy {
        url = uri("https://ajax.googleapis.com/ajax/libs")
        patternLayout {
            artifact("[organization]/[revision]/[module].[ext]")
        }
        metadataSources {
            artifact()
        }
    }
}

configurations {
    create("js")
}

dependencies {
    "js"("jquery:jquery:3.2.1@js")
}
build.gradle
repositories {
    ivy {
        url = 'https://ajax.googleapis.com/ajax/libs'
        patternLayout {
            artifact '[organization]/[revision]/[module].[ext]'
        }
        metadataSources {
            artifact()
        }
    }
}

configurations {
    js
}

dependencies {
    js 'jquery:jquery:3.2.1@js'
}

Step 2: Resolving an Artifact with a Classifier

Some libraries provide multiple variations or flavors of an artifact. In Java, a library may publish:

  • A compiled artifact with class files.

  • A separate artifact containing source code.

  • Another one with Javadocs.

Similarly, in JavaScript, libraries often have:

  • An uncompressed version.

  • A minified version (optimized for production).

To specify a particular variation, you can use a classifier. In Gradle, classifiers allow you to fetch a specific artifact within a module.

Instead of downloading the uncompressed jquery.js file, you can fetch the minified version (jquery.min.js) by specifying the classifier min:

build.gradle.kts
repositories {
    ivy {
        url = uri("https://ajax.googleapis.com/ajax/libs")
        patternLayout {
            artifact("[organization]/[revision]/[module](.[classifier]).[ext]")
        }
        metadataSources {
            artifact()
        }
    }
}

configurations {
    create("js")
}

dependencies {
    "js"("jquery:jquery:3.2.1:min@js")
}
build.gradle
repositories {
    ivy {
        url = 'https://ajax.googleapis.com/ajax/libs'
        patternLayout {
            artifact '[organization]/[revision]/[module](.[classifier]).[ext]'
        }
        metadataSources {
            artifact()
        }
    }
}

configurations {
    js
}

dependencies {
    js 'jquery:jquery:3.2.1:min@js'
}

Summary

Gradle can fetch non-Java artifacts like JavaScript libraries from external repositories:

  • Use artifact-only notation (@) when resolving dependencies that lack metadata.

  • Use classifiers to specify different versions or variations of an artifact.