Signing plugin on Kotlin Multiplatform with HTML jar artifact gets a cross-target dependency error

As part of Dokka upgrade V2 I need to publish an HTML jar of documentation from Dokka. I use this block to generate that jar:

val htmlJarTask = tasks.register<Jar>("htmlJar") {
    archiveClassifier.set("htmldoc")
    dependsOn(tasks.dokkaGeneratePublicationHtml)
    from(project.layout.buildDirectory.dir("dokka/html"))
}

I then include this task as an artifact in the publishing block. This is a kotlin multiplatform project with Android, JVM, and Linux targets to be published. There are other targets but only these build on the linux host where this is being run. The signing plugin is defined simply like this:

signing {
    isRequired = true
    sign(publishing.publications)
}

Attempting to run publishToMavenLocal then fails with this error:

FAILURE: Build failed with an exception.

* What went wrong:
A problem was found with the configuration of task ':KmpIO:signKotlinMultiplatformPublication' (type 'Sign').
  - Gradle detected a problem with the following location: '/mnt/Projects/KmpIO/KmpIO/build/libs/KmpIO-0.1.8-htmldoc.jar.asc'.
    
    Reason: Task ':KmpIO:publishJvmPublicationToMavenLocal' uses this output of task ':KmpIO:signKotlinMultiplatformPublication' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
    
    Possible solutions:
      1. Declare task ':KmpIO:signKotlinMultiplatformPublication' as an input of ':KmpIO:publishJvmPublicationToMavenLocal'.
      2. Declare an explicit dependency on ':KmpIO:signKotlinMultiplatformPublication' from ':KmpIO:publishJvmPublicationToMavenLocal' using Task#dependsOn.
      3. Declare an explicit dependency on ':KmpIO:signKotlinMultiplatformPublication' from ':KmpIO:publishJvmPublicationToMavenLocal' using Task#mustRunAfter.

Each target platform should use the same jar for itself and sign its copy during build. Why does gradle detect these target platforms crossovers? In this case the “JVM” target should need no dependency from the “Multiplatform” target. The jar should be copied for each target’s publication.

FYI as far as I can tell this is nearly identical to how I did a javadoc jar from Doka V1, and that worked fine. I don’t know why this HTML jar artifact is different.

Thanks in advance for any info/help.

Besides that practically all explicit dependsOn that do not have a lifecycle task on the left-hand side are a code smell and usually show that you are not properly wiring task outputs to task inputs, the error you get almost never means you should add any dependencies or ordering constraints, but most often it means you have tasks with overlapping outputs which is always a bad idea. If you for example have task A that has directory foo as output directory, task B that has file foo/b as output file, and task C that has task B outputs as inputs, Gradle will complain that you use As outputs in C without dependency / ordering constraint as foo/b is also declared as output of A and these overlapping outputs are what should usually be fixed.

Thanks! I’m having trouble though figuring out how to diagnose what’s happening between the publish and signing plugins to research your points. To anyone interested I’m also discussing this on the Dokka slack channel, see this link for more details: Dokka Slack thread on signing error with HTML jar. Any pointers on what I should query in the various tasks that publish/signing is doing to diagnose this?

Well, I guess what happens is, that you add e same artifact to multiple publications and as you configure signing for all publications then have a task for each of those publications that signs the same artifact to the same signature file and thus have the mentioned outputs overlap.

You can for example check the task outputs.

Thanks to [Slack](https://Oleg Yukhnevich [JetBrains]), he has a workaround for a bug in the signing plugin that causes this error in KMP projects using an artifact shared across multiple targets.
Thanks for your help! It got me to add some diagnostic code to identify exactly what sign plugin is doing, which Oleg then recognized as something he’d also seen. Hope this is useful to someone else :slight_smile:

1 Like