skip to content

A teammate applied maven-publish but their published module has no dependencies and consumers can't resolve transitive libraries. What likely went wrong and how do you fix it?

level: middleimportance: must knowfreq 45%

answer

  1. symptom: empty <dependencies> in POM
  2. cause: artifact(jar) instead of from(components)
  3. fix: from(components["java"])
  4. check generatePomFile.../build/publications
  5. or java plugin not applied

basics

~10 s

They almost certainly attached the jar with artifact(jar) instead of calling from(components["java"]). Switch to from(components["java"]) so the publication carries dependency metadata and the POM lists transitive dependencies.

solid answer

~40 s

The symptom — jar present but no transitive dependencies — points to a publication built from a bare artifact rather than a software component. `artifact(tasks.jar)` publishes only the file; it contributes no dependency metadata, so the generated POM has an empty `<dependencies>` block and Gradle Module Metadata is absent. The fix is to declare the publication with `from(components["java"])`, which derives both the jar *and* the api/implementation dependencies (mapped to compile/runtime scopes) plus the `.module` metadata. Other related causes to check: the `java`/`java-library` plugin wasn't applied (so there's no `java` component), or the project uses `compileOnly` for deps that genuinely shouldn't be exported. After fixing, verify with `generatePomFileForMavenPublication` and inspect the generated POM.

code

kotlin · 9 lines
kotlin
// WRONG — no dependency metadata
create<MavenPublication>("maven") {
    artifact(tasks.named("jar"))
}

// RIGHT — dependencies + module metadata
create<MavenPublication>("maven") {
    from(components["java"])
}

go deeper

for a junior

Identify that the fix is to use from(components["java"]) instead of attaching the jar manually.

for a middle

Explain why artifact() drops metadata and how to verify the corrected POM.

for a senior

Also consider missing java plugin and compileOnly scoping as alternate root causes.

for a principal

Bake from(components[...]) into a shared convention plugin so the mistake can't recur across modules.

## The classic failure mode "My library publishes but consumers don't get its dependencies" is the single most common maven-publish mistake. It almost always means the publication was assembled from a raw artifact instead of a software component. ## Why artifact(jar) loses dependencies ```kotlin publishing { publications { create<MavenPublication>("maven") { artifact(tasks.named("jar")) // BUG: file only } } } ``` `artifact(...)` attaches a single file to the publication. It knows nothing about your `dependencies {}` block, so: - The generated POM has no `<dependencies>`. - No Gradle Module Metadata is produced. - Consumers download the jar but none of its transitive libraries → `NoClassDefFoundError` at runtime. ## The fix ```kotlin publishing { publications { create<MavenPublication>("maven") { from(components["java"]) // jar + dependency metadata } } } ``` `from(components["java"])` reads the `java` component, so the POM lists `api`/`implementation` deps in `compile`/`runtime` scope and the `.module` file is emitted. ## Verifying Run the generated task `generatePomFileForMavenPublication` (the exact name derives from your publication's name) and read the produced `pom.xml` under `build/publications/...` to confirm the `<dependencies>` block is populated. Publishing to Maven Local (`publishToMavenLocal`) and inspecting `~/.m2` is another quick check. ## Adjacent causes - **No `java` component**: the `java`/`java-library` plugin wasn't applied, so `components["java"]` doesn't exist. - **Wrong configuration**: declaring deps as `compileOnly` deliberately excludes them from the published metadata — sometimes intended, sometimes the actual bug.

  • How would you confirm the fix produced a correct POM?
    Run the generated `generatePomFileForMavenPublication` task and inspect the POM under `build/publications/...`, or `publishToMavenLocal` and read it in `~/.m2`; the `<dependencies>` block should now be populated.
  • Could the missing dependencies be intentional?
    Yes — if the deps were declared as `compileOnly`, they're deliberately excluded from published metadata. You'd verify whether they should actually be `api`/`implementation`.

saying these in an interview costs you the question

  • Trying to fix it by manually listing dependencies in a custom POM block instead of using from(components[...]).
  • Forgetting that artifact(...) contributes no dependency metadata at all.

context