What is the difference between components.java and components.javaPlatform, and when do you publish each?
answer
- java = library + jar
- javaPlatform = BOM, no jar
- constraints → dependencyManagement
- platform(...) for alignment
- separate projects
basics
~10 scomponents.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 sThese 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// 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
Know java = library with a jar; javaPlatform = BOM with no jar.
Explain constraints publishing as dependencyManagement and importing via platform(...).
Discuss separate-project topology and allowDependencies trade-offs.
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).