Summary
Dependencies on the jarJar configuration don't pick up constraints from a platform(...) BOM. When a dependency has no explicit version, this surfaces as a resolution error (empty version):
Could not resolve all dependencies for configuration ':neoforge:jarJar'.
> Could not find net.kyori:adventure-text-serializer-legacy:.
> Could not find net.kyori:adventure-serializer-configurate4:.
The BOM itself is resolved (it appears in the dependency tree, and dependencyInsight shows its runtimeElements/category=platform variant selected), but its constraints don't seem to be applied to the other dependencies. When a dependency does have a version, the constraint is silently ignored instead, which could yield a version other than what the BOM would select.
Versions
- ModDevGradle: 2.0.141
- Gradle: 9.6.1
Steps to reproduce
Minimal build.gradle.kts (no NeoForge needed) — the version-less case is the most visible form:
plugins { `java` }
repositories { mavenCentral() }
val jarJar = configurations.create("jarJar") {
isTransitive = false
isCanBeResolved = true
isCanBeConsumed = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
}
}
dependencies {
"jarJar"(platform("net.kyori:adventure-bom:5.2.0"))
"jarJar"("net.kyori:adventure-text-serializer-legacy") // no version -> relies on BOM
}
./gradlew dependencies --configuration jarJar:
jarJar
+--- net.kyori:adventure-bom:5.2.0
\--- net.kyori:adventure-text-serializer-legacy FAILED
Setting isTransitive = true (everything else unchanged) makes it resolve to 5.2.0, so the issue appears specific to the non-transitive configuration. The configuration attributes don't seem to be a factor — it reproduces without them as well.
Expected behavior
jarJar should apply platform()/BOM constraints like other resolvable configurations — both to supply versions for version-less dependencies and to constrain versioned ones.
Notes
The jarJar configuration is created with setTransitive(false):
|
configuration.setTransitive(false); |
On a non-transitive configuration, a platform() BOM is resolved but its dependency constraints don't appear to propagate to sibling dependencies.
For reference, fabric-loom's include configuration doesn't exhibit this — it keeps the configuration transitive and copies each declared dependency into a detached resolvable configuration individually, marking regular module dependencies non-transitive while leaving platform/enforcedPlatform BOMs transitive so their constraints propagate.
Workaround
Supply the version via a direct constraints {} block on jarJar, which is applied regardless of transitivity:
constraints {
add("jarJar", "net.kyori:adventure-text-serializer-legacy") { version { require("5.2.0") } }
add("jarJar", "net.kyori:adventure-serializer-configurate4") { version { require("5.2.0") } }
}
Summary
Dependencies on the
jarJarconfiguration don't pick up constraints from aplatform(...)BOM. When a dependency has no explicit version, this surfaces as a resolution error (empty version):The BOM itself is resolved (it appears in the dependency tree, and
dependencyInsightshows itsruntimeElements/category=platformvariant selected), but its constraints don't seem to be applied to the other dependencies. When a dependency does have a version, the constraint is silently ignored instead, which could yield a version other than what the BOM would select.Versions
Steps to reproduce
Minimal
build.gradle.kts(no NeoForge needed) — the version-less case is the most visible form:plugins { `java` } repositories { mavenCentral() } val jarJar = configurations.create("jarJar") { isTransitive = false isCanBeResolved = true isCanBeConsumed = false attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) } } dependencies { "jarJar"(platform("net.kyori:adventure-bom:5.2.0")) "jarJar"("net.kyori:adventure-text-serializer-legacy") // no version -> relies on BOM }./gradlew dependencies --configuration jarJar:Setting
isTransitive = true(everything else unchanged) makes it resolve to5.2.0, so the issue appears specific to the non-transitive configuration. The configuration attributes don't seem to be a factor — it reproduces without them as well.Expected behavior
jarJarshould applyplatform()/BOM constraints like other resolvable configurations — both to supply versions for version-less dependencies and to constrain versioned ones.Notes
The
jarJarconfiguration is created withsetTransitive(false):ModDevGradle/src/main/java/net/neoforged/moddevgradle/tasks/JarJar.java
Line 82 in 846b2d7
On a non-transitive configuration, a
platform()BOM is resolved but its dependency constraints don't appear to propagate to sibling dependencies.For reference, fabric-loom's
includeconfiguration doesn't exhibit this — it keeps the configuration transitive and copies each declared dependency into a detached resolvable configuration individually, marking regular module dependencies non-transitive while leavingplatform/enforcedPlatformBOMs transitive so their constraints propagate.Workaround
Supply the version via a direct
constraints {}block onjarJar, which is applied regardless of transitivity:constraints { add("jarJar", "net.kyori:adventure-text-serializer-legacy") { version { require("5.2.0") } } add("jarJar", "net.kyori:adventure-serializer-configurate4") { version { require("5.2.0") } } }