# Metadata Formats

version 9.0.0

Dependency metadata refers to the information associated with a dependency that describes its characteristics, relationships, and requirements.

This metadata includes details such as:

1. Identity: Module dependencies are uniquely identified by their group, name, and version (GAV) coordinates.

2. Dependencies: A list of other binaries that this dependency requires, including their versions.

3. Variants: Different forms of the component (e.g., compile, runtime, apiElements, runtimeElements) that can be consumed in different contexts.

4. Artifacts: The actual files (like JARs, ZIPs, etc.) produced by the component, which may include compiled code, resources, or documentation.

5. Capabilities: Describes the functionality or features that a module provides or consumes, helping to avoid conflicts when different modules provide the same capability.

6. Attributes: Key-value pairs used to differentiate between variants (e.g. `org.gradle.jvm.version:8`).

Depending on the repository type, dependency metadata are stored in different formats:

- Gradle: Gradle Module Metadata (`.module`) files

- Maven: Maven POM (`pom.xml`) files

- Ivy: Ivy Descriptor (`ivy.xml`) files

Some repositories may contain multiple types of metadata for a single component. When Gradle publishes to a Maven repository, it publishes both a Gradle Module Metadata (GMM) files and a Maven POM file.

This metadata plays a crucial role in dependency resolution, by allowing the dependencies of binary artifacts to be tracked alongside the artifact itself. By reading dependency metadata, Gradle is able to determine which versions of other artifacts a given dependency requires.

| In Maven, a module can have one and only one artifact. In Gradle and Ivy, a module can have multiple artifacts.

## Supported metadata formats

External module dependencies require module metadata so that Gradle can determine the transitive dependencies of a module. Gradle supports various metadata formats to achieve this.

### Gradle Module Metadata (GMM) files

Gradle Module Metadata is specifically designed to support all features of Gradle’s dependency management model, making it the preferred format.

You can find the specification here.

    {
      "formatVersion": "1.1",
      "component": {
        "group": "com.example",
        "module": "my-library",
        "version": "1.0"
      }
    }

### POM files

Gradle natively supports Maven POM files. By default, Gradle will first look for a POM file. However, if the file contains a special marker, Gradle will use Gradle Module Metadata instead.

    <project xmlns="http://maven.apache.org/POM/4.0.0">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example</groupId>
      <artifactId>my-library</artifactId>
      <version>1.0</version>
    </project>

### Ivy files

Gradle also supports Ivy descriptor files. Gradle will first look for an `ivy.xml` file, but if this file contains a special marker, it will use Gradle Module Metadata instead.

    <ivy-module version="2.0">
      <info organisation="com.example" module="my-library" revision="1.0"/>
      <dependencies>
        <dependency org="org.example" name="dependency" rev="1.2"/>
      </dependencies>
    </ivy-module>

## Supported metadata sources

When searching for a component in a repository, Gradle checks for supported metadata file formats by default:

- Gradle first looks for `.module` (Gradle module metadata) files.

- In a Maven repository, Gradle then looks for `.pom` files.

- In an Ivy repository, it checks for `ivy.xml` files.

- In a flat directory repository, it looks directly for `.jar` files without expecting any metadata.

If you define a custom repository, you can configure how Gradle searches for metadata. For instance, you can set up a Maven repository will optionally resolve JARs that don’t have associated POM files. This is done by configuring metadata sources for the repository:

build.gradle.kts

    repositories {
        maven {
            url = uri("http://repo.mycompany.com/repo")
            metadataSources {
                mavenPom()
                artifact()
            }
        }
    }

build.gradle

    repositories {
        maven {
            url = "http://repo.mycompany.com/repo"
            metadataSources {
                mavenPom()
                artifact()
            }
        }
    }

You can specify multiple metadata sources, and Gradle will search through them in a predefined order. The following metadata sources are supported:

Metadata source | Description | Default Order | Maven | Ivy / flat dir
--- | --- | --- | --- | ---
`gradleMetadata()` | Look for Gradle `.module` files | 1st | yes | yes
`mavenPom()` | Look for Maven `.pom` files | 2nd | yes | yes
`ivyDescriptor()` | Look for `ivy.xml` files | 2nd | no | yes
`artifact()` | Look directly for artifact without associated metadata | 3rd | yes | yes

By default, Gradle will require that a dependency has associated metadata.

To relax this requirement and allow Gradle to resolve artifacts without associated metadata, specify the `artifact` metadata source:

    mavenCentral {
        metadataSources {
            mavenPom()
            artifact()
        }
    }

The above example instructs Gradle to first look for component metadata from a POM file, and if not present, to derive metadata from the artifact itself.

For example, if you declare a module dependency, Gradle looks for a module metadata file (`.module`, `.pom`, or `ivy.xml`) in the repositories. If such a module metadata file exists, it is parsed, and the artifacts of this module (e.g., `hibernate-3.0.5.jar`) as well as its dependencies (e.g., `cglib`) are downloaded. If no such module metadata file exists, you need to configure metadata sources definitions to look for an artifact file called `hibernate-3.0.5.jar` directly:

    repositories {
        maven {
            url "https://repo.example.com/maven"
            metadataSources {
                mavenPom()   // Look for a POM file
                artifact()   // If no metadata is found, look for JARs directly
            }
        }
    }

When parsing metadata files (Ivy or Maven), Gradle checks for a marker that indicates the presence of a matching Gradle Module Metadata file. If found, Gradle will prefer the Gradle metadata.

To disable this behavior, use the `ignoreGradleMetadataRedirection()` option:

build.gradle.kts

    repositories {
        maven {
            url = uri("http://repo.mycompany.com/repo")
            metadataSources {
                mavenPom()
                artifact()
                ignoreGradleMetadataRedirection()
            }
        }
    }

build.gradle

    repositories {
        maven {
            url = "http://repo.mycompany.com/repo"
            metadataSources {
                mavenPom()
                artifact()
                ignoreGradleMetadataRedirection()
            }
        }
    }