skip to content

What is the difference between components.java and components.javaPlatform, and when do you publish each?

level: middleimportance: should knowfreq 40%

answer

  1. java = library + jar
  2. javaPlatform = BOM, no jar
  3. constraints → dependencyManagement
  4. platform(...) for alignment
  5. separate projects

basics

~10 s

components.java (from the java plugin) publishes a library: a jar plus its dependencies. components.javaPlatform (from the java-platform plugin) publishes a platform/BOM: only dependency constraints, no jar.

solid answer

~40 s

These are two different software components for two different publishing intents. `components.java` is registered by the `java`/`java-library` plugin and represents a **library** — it carries the main jar artifact and the `apiElements`/`runtimeElements` variants with real dependencies, producing a normal POM (or GMM) with artifacts. `components.javaPlatform` is registered by the `java-platform` plugin and represents a **platform** (a Gradle BOM) — it has **no jar**, only dependency **constraints** declared in the `api`/`runtime` platform configurations, which publish as a `pom` of type `pom` (a Maven BOM with `<dependencyManagement>`). You publish `java` when shipping consumable code; you publish `javaPlatform` when shipping a recommendation/alignment artifact that other builds import via `platform(...)` to align versions without pulling code.

code

kotlin · 16 lines
kotlin
// BOM project publishing components.javaPlatform
plugins { `java-platform`; `maven-publish` }

javaPlatform { allowDependencies() } // only if real deps needed

dependencies {
  constraints {
    api("org.junit.jupiter:junit-jupiter:5.10.2")
  }
}

publishing {
  publications {
    create<MavenPublication>("bom") { from(components["javaPlatform"]) }
  }
}

go deeper

for a junior

Know java = library with a jar; javaPlatform = BOM with no jar.

for a middle

Explain constraints publishing as dependencyManagement and importing via platform(...).

for a senior

Discuss separate-project topology and allowDependencies trade-offs.

for a principal

Frame platforms as an org-wide version-alignment governance mechanism feeding consumer dependency hygiene.

## Two components, two intents Gradle ships distinct components for distinct publishing goals. ### `components.java` — a library Registered by the `java` plugin. It bundles: - the **main jar** artifact, - the **`apiElements`** variant (compile-time dependencies, `api` scope), - the **`runtimeElements`** variant (runtime dependencies). Publishing it yields a standard module: a jar plus a POM whose `<dependencies>` come from those variants, plus GMM. Consumers get code. ### `components.javaPlatform` — a platform / BOM Registered by the `java-platform` plugin. A platform has **no artifact**; its purpose is *version alignment*. You declare **constraints** (and optionally hard dependencies) in the platform's `api`/`runtime` configurations via the `dependencies { constraints { ... } }` / `api(...)` DSL inside a `dependencies` block scoped to the platform. Publishing it produces a Maven BOM — a `pom` packaging artifact populated as `<dependencyManagement>` — and corresponding GMM. Consumers import it with `implementation(platform("group:my-bom:1.0"))` to align versions without dragging in code. ```kotlin // platform project plugins { `java-platform`; `maven-publish` } dependencies { constraints { api("com.google.guava:guava:33.0.0-jre") api("org.slf4j:slf4j-api:2.0.12") } } publishing { publications { create<MavenPublication>("platform") { from(components["javaPlatform"]) } } } ``` ## Choosing which to publish - Shipping **code others compile/run against** → `from(components.java)`. - Shipping a **version recommendation/alignment artifact** (BOM) → `from(components.javaPlatform)`. You would typically publish them from **separate projects** — a library project and a dedicated platform project — because applying both `java-library` and `java-platform` to one project conflicts (one wants a jar, the other forbids it). ## allowDependencies By default `java-platform` rejects hard dependencies (constraints only). Set `javaPlatform { allowDependencies() }` if you legitimately need the platform to also declare real dependencies.

  • Can you apply both java-library and java-platform to the same project?
    Not cleanly — they conflict on whether a jar exists. Use separate projects, typically a library project and a dedicated platform project.
  • How do constraints in a published platform appear in the POM?
    As `<dependencyManagement>` entries in a BOM-style POM (packaging `pom`), not as direct `<dependencies>`.

saying these in an interview costs you the question

  • Saying a platform publishes a jar — it has no artifact.
  • Confusing `platform(...)` (consume a BOM) with `java-platform` (produce one).

context