skip to content

How does a consumer enable or disable Gradle Module Metadata resolution, and what are the trade-offs of turning it off on either side?

level: seniorimportance: nice to knowfreq 22%

answer

  1. metadataSources { gradleMetadata()/mavenPom()/artifact() }
  2. GMM preferred by default when present
  3. disable producing: GenerateModuleMetadata.enabled=false
  4. off => lose variants/capabilities/strict-reject
  5. escape hatch, not a default

basics

~10 s

Consuming GMM is on by default. You can opt out per-repository (metadataSources only the POM) or disable producing it via the GenerateModuleMetadata task. Turning it off loses variant-aware resolution and rich-version fidelity.

solid answer

~40 s

On the **consumer** side, GMM resolution is enabled by default: when both a `.module` and a `.pom` exist, Gradle prefers the `.module`. You control this per repository through `metadataSources { }` — e.g. declare only `mavenPom()` (or `artifact()`) to ignore GMM, or `gradleMetadata()` to require it. On the **producer** side, GMM is generated automatically for component-based publications and can be switched off by disabling the `GenerateModuleMetadata` task. The trade-offs: disabling GMM consumption means you lose variant-aware matching, capabilities-as-conflict, and strict/reject version semantics, falling back to the coarser POM view — occasionally a deliberate workaround for a broken published `.module`, but generally a downgrade. Disabling GMM production strips those guarantees for *all* your downstream Gradle consumers, so it's reserved for special cases (e.g. avoiding accidental variant leakage), not a default.

code

kotlin · 8 lines
kotlin
repositories {
    maven {
        url = uri("https://repo.example.com")
        metadataSources {
            mavenPom() // ignore a broken .module: resolve from POM only
        }
    }
}

go deeper

for a junior

Know GMM is used by default and there's a way to opt out.

for a middle

Configure metadataSources correctly and name the GenerateModuleMetadata task for disabling production.

for a senior

Articulate the concrete capabilities lost when GMM is off and when each opt-out is a justified escape hatch.

for a principal

Decide org policy: keep GMM enabled, standardize repository metadataSources, and document the narrow cases for disabling either side.

## Consumer side: metadataSources Each repository can be told which metadata to trust: ```kotlin repositories { maven { url = uri("https://repo.example.com") metadataSources { gradleMetadata() // read the .module file (default-preferred) mavenPom() // and/or the POM as fallback // artifact() // last-resort: infer from the artifact alone } } } ``` - By default Gradle uses `gradleMetadata()` **and** `mavenPom()`, preferring GMM when present. - To **ignore** a broken or unwanted `.module`, list only `mavenPom()` (and/or `artifact()`). Gradle then resolves purely from the POM and you lose variant fidelity. - The POM marker comment that normally signals "a `.module` exists" is honored unless you remove `gradleMetadata()`. ## Producer side: disabling generation GMM is produced by the `GenerateModuleMetadata` task whenever you publish a software component. To stop it: ```kotlin tasks.withType<GenerateModuleMetadata>().configureEach { enabled = false } ``` This publishes only the POM + artifacts. Use it rarely — for instance, if a tool in your consumers' chain mishandles GMM, or you must publish a stripped-down POM-only module. ## Trade-offs Turning GMM **off** (either side) costs you: - **Variant-aware resolution** — no API/runtime split, no per-platform selection. - **Capabilities** — no automatic conflict detection between modules providing the same capability. - **Rich versions** — `strictly`/`rejects`/constraints degrade to the POM's limited expressiveness. - **Feature variants / optional features** — invisible to a POM-only consumer. Turning it **on** (the default) costs essentially nothing for Gradle consumers and stays interoperable for Maven consumers (who read the POM). So the prevailing guidance is: keep GMM enabled; disable consumption only as a targeted escape hatch for a specific bad module, and disable production only with a clear, documented reason. ## Verifying behavior Use `./gradlew dependencyInsight` and `--info` resolution logs to confirm whether a dependency was resolved via GMM or POM, and `./gradlew outgoingVariants` on the producer to see what GMM will advertise.

  • By default, if both a `.module` and `.pom` are present, which wins?
    The `.module` (Gradle Module Metadata) is preferred; the POM acts as the fallback for non-Gradle consumers or when GMM consumption is disabled.
  • Why might you configure `metadataSources { mavenPom() }` only?
    To work around a published `.module` that's malformed or advertises variants you don't want, forcing Gradle to resolve from the POM instead — accepting the loss of variant fidelity.

saying these in an interview costs you the question

  • Believing GMM consumption must be manually enabled (it's on by default).
  • Recommending disabling GMM production as a routine practice rather than a rare escape hatch.

context