Reobf jar variant points to the wrong artifact location when using Groovy DSL
0dinD opened this issue · comments
Paperweight version: 1.3.5
Gradle version: 7.3.3
Minimal example repo to reproduce the issue: https://github.com/0dinD/paperweight-bug
I have a submodule for NMS code that uses paperweight-userdev. I now want to depend on the reobfuscated jar artifact from the submodule in the main plugin module. So i do something like this:
dependencies {
runtimeOnly project(path: ":nms-submodule", configuration: "reobf")
}
For context, the NMS submodule is bundled into the plugin using Shadow and then loaded dynamically based on the server version, similar to how WorldEdit and other plugins do it.
But when I build the shadow jar, it doesn't contain the classes from the NMS submodule. Running ./gradlew clean shadowJar --info
yields the following information in the output:
> Task :shadowJar
file or directory '/path/to/paperweight-bug/nms-submodule/.gradle/caches/paperweight/taskCache/reobfJar.jar', not found
This prompted me to check ./gradlew :nms-submodule:outgoingVariants
, which reports:
--------------------------------------------------
Variant reobf
--------------------------------------------------
Capabilities
- org.example:nms-submodule:1.0.0-SNAPSHOT (default capability)
Attributes
- io.papermc.paperweight.obfuscation = obfuscated
- org.gradle.category = library
- org.gradle.dependency.bundling = external
- org.gradle.libraryelements = jar
- org.gradle.usage = java-runtime
Artifacts
- .gradle/caches/paperweight/taskCache/reobfJar.jar (artifactType = jar)
So the problem is that the reobf
variant points to the wrong artifact location, a temporary jar in the cache which gets deleted before the Shadow plugin can use it.
Strangely enough, this only happens when using the Groovy DSL, not the Kotlin DSL (even when the build scripts are identical). You can see this by renaming the nms-submodule/build.gradle
file in my example repo to build.gradle.kts
(no other changes required). Inspecting the output of ./gradlew :nms-submodule:outgoingVariants
I would expect that the correct artifact location gets assigned even when using the Groovy DSL.
I see that the artifact location is assigned here:
paperweight/paperweight-userdev/src/main/kotlin/PaperweightUser.kt
Lines 154 to 157 in 9496216
My best guess is that the afterEvaluate
above is causing issues, but I'm not sure why it would work in the Kotlin DSL if it doesn't work in Groovy. Before afterEvaluate
runs the output location seems to be set from
and it looks like defaultOutput()
is .gradle/caches/paperweight/taskCache/reobfJar.jar
.
Now, I did manage to come up with a workaround, by manually assigning the correct artifact location:
configurations.reobf {
outgoing.artifact(layout.buildDirectory.file("libs/${project.name}-${project.version}.jar"))
}
I don't know enough about the internals about this plugin to know what the proper solution is, but maybe the output location should be set before afterEvaluate
? Or maybe this is just a Gradle bug, in which case I can open a bug report there instead. Or perhaps I've misunderstood something and there's a better solution, which I'd be happy to hear.
Something about https://github.com/0dinD/paperweight-bug/blob/3aa5e892186874faae7cce1ba732653cc1f21aad/nms-submodule/build.gradle#L21-L23 looks to be causing publications to be evaluated early with groovy.
Running with groovy: https://paste.gg/p/anonymous/8f510999dc134427a934470dd4d85fde
With kotlin: https://paste.gg/p/anonymous/4a17773046864caa9528f7d3538dff4e
Changing the linked lines to
tasks.named("assemble") {
dependsOn(tasks.named("reobfJar"))
}
allowed it to work as expected with a groovy script: https://paste.gg/p/anonymous/dea12e03702c40a8967e26bf27eaa044
Ah, I think I see what's happening now. Those lines were pretty much taken from:
So that's why I assumed the problem was related to something else. But for whatever reason, the Groovy DSL behaves differently from the Kotlin DSL in this instance, see gradle/gradle#15720. So in the Groovy DSL you currently need to use the more verbose tasks.named
notation for task configuration avoidance, like you did in your example.
Thanks for helping me figure this out!