Version catalogs vs platforms, aren't they the same?

Recently I’ve been looking into platforms and it seems to me they’re the same as version catalogs, the only difference from what I can tell is semantics.

e.g.
platform

plugins {
  `java-platform`
}
dependencies {
  constraints {
    api("my.dependency:dependency:1.2.3")
  }
}

build.gradle

plugins {
  `java-library`
}
dependencies {
  implementation(platform(project(":platform"))
  implementation("my.dependency:dependency")
}

Is functionally equivalent to:
deps.versions.toml

[libs]
dependency = { module = "my.dependency:dependency", version = "1.2.3" }

build.gradle

plugins {
  `java-library`
}
dependencies {
  implementation(deps.libs.dependency)
}

Is there something I’m missing here?

They are not at all the same, though they are related. You can even use both together. But it is all detailed in the documentation at Sharing dependency versions between projects

1 Like

Ah, thanks for that, I didn’t know you could publish platforms and consume them in multiple projects.

That’s actually not a difference.
You can publish platforms as well as version catalogs and consume both in multiple projects.

1 Like

@Vampire thanks for the elaboration here. i read the document - and still am not able to judge what in the case of junit should be chosen, what type do you recommend? using catalog and platform:

testImplementation(platform(libs.junit.bom))
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")

or using catalog only, or it does not matter?

testImplementation(libs.junit.api)
testImplementation(libs.junit.params)
testRuntimeOnly(libs.junit.engine)

That is not the kind of “using platform” that is meant here.

You can make a project in your build that applies the java-platform plugin and there define constraints (also coming from a version catalog eventually) and then make your other projects depend on that platform to control the version.

In the context here, you do not use platform, but you mix up using a 3rd-party platform vs using strings vs using version catalog entries.

I would say it should look like

testImplementation(platform(libs.junit.bom))
testImplementation(libs.junit.api)
testImplementation(libs.junit.params)
testRuntimeOnly(libs.junit.engine)

with the lower three not having a version in the version catalog