I wrote a plugin generating Kotlin code (using KotlinPoet) and wanted to include the output of that plugin in the build path.
The Kotlin compilation works fine, though when calling gradle sourcJar build
, it tells me
A problem was found with the configuration of task ':generateClasses' (type 'GenerateClassesTask').
- Gradle detected a problem with the following location: '/Users/.../build/generated/sources/kotlin'.
Reason: Task ':sourcesJar' uses this output of task ':generateClasses' 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 ':generateClasses' as an input of ':sourcesJar'.
2. Declare an explicit dependency on ':generateClasses' from ':sourcesJar' using Task#dependsOn.
3. Declare an explicit dependency on ':generateClasses' from ':sourcesJar' using Task#mustRunAfter.
For more information, please refer to https://docs.gradle.org/8.13/userguide/validation_problems.html#implicit_dependency in the Gradle documentation.
After some debugging I found out, that the :sourcesJar
task is not yet registered when the plugin is applied. Additionally gradle sourcesJar
succeeds (and the jar does not contain the generated sources) while gradle compileKotlin sourcesJar
fails with the error above, as if the kotlinCompile
task would add the generated sources to the input of the sourceJar task.
Can someone tell me, how I should configure the task dependencies to avoid the error correctly?
(Any yes the workaround is probably to exclude the generated folder from sources Jar, but I would like to understand where the cause of the problem is and to solve it.
Here the frame for the plugin and the task
class SomeGeneratorPlugin : Plugin<Project> {
override fun apply(project: Project) {
val task = project.tasks.register("generateClasses", GenerateClassesTask::class.java)
project.getTasksByName("compileKotlin", false).forEach {
it.dependsOn(task)
}
project.getTasksByName("sourcesJar", false).forEach {
it.dependsOn(task)
}
project.extensions
.findByType<JavaPluginExtension>()
?.sourceSets
?.get("main")
?.java
?.srcDir("build/generated/sources/kotlin")
}
}
@CacheableTask
open class GenerateClassesTask : DefaultTask() {
@TaskAction
fun generate() {
// writes Kotlin code to outputDir
}
@OutputDirectory
val outputDir: java.io.File =
project.layout.buildDirectory
.dir("generated/sources/kotlin")
.get()
.asFile
}