quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.69k stars 2.65k forks source link

Gradle build with KSP fails with "circular dependency" after Quarkus 2.13.0 #29698

Open tanadeau opened 1 year ago

tanadeau commented 1 year ago

Describe the bug

When using KSP (Kotlin Symbol Processing, see https://kotlinlang.org/docs/ksp-overview.html), the Gradle build fails with a "circular dependency" starting with Quarkus 2.13.0 (up to the latest 2.14.2). It worked fine in 2.12.3.

Expected behavior

Build succeeds

Actual behavior

Build fails with circular dependency:

FAILURE: Build failed with an exception.

* What went wrong:
Circular dependency between the following tasks:
:backend:kspKotlin
+--- :backend:quarkusGenerateCode
|    \--- :backend:processResources
|         \--- :backend:kspKotlin (*)
\--- :backend:quarkusGenerateCodeDev
     \--- :backend:processResources (*)

(*) - details omitted (listed previously)

How to Reproduce?

Reproducer: quarkus-reproducer.zip

Steps to reproduce:

  1. ./gradlew clean build (will fail)
  2. In gradle.properties, change quarkusVersion from 2.13.0.Final to 2.12.3.Final.
  3. ./gradlew clean build (will succeed)

If quarkusVersion is greater or equal to 2.13.0.Final, it will fail in the same way, including the latest version (2.14.2.Final).

Output of uname -a or ver

Darwin C02YK01PLVCG-ML 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64 x86_64

Output of java -version

openjdk version "17.0.3" 2022-04-19

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.13.0

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 7.6

Additional information

This occurs in at least Gradle 7.5.1 and 7.6.

quarkus-bot[bot] commented 1 year ago

/cc @evanchooly, @geoand, @glefloch, @quarkusio/devtools

geoand commented 1 year ago

@glefloch @aloubyansky did we change something in the Gradle plugin?

aloubyansky commented 1 year ago

@glefloch it appears https://github.com/quarkusio/quarkus/pull/27764 is what breaks it.

LazaroR94 commented 1 year ago

Has this been addressed yet? I am also receiving this error on Quarkus 2.14.2 and KSP 1.6.21-1.0.6.

Augustyn commented 1 year ago

I've managed to mitigate the problem on my side, with a below snippet in my build.gradle.kts file:

project.afterEvaluate {
        tasks.findByPath("app:quarkusGenerateCode")?.let {
            it.setDependsOn(it.dependsOn.map { it as Provider<*> }.filter { it.get() !is ProcessResources })
        }
        tasks.findByPath("app:quarkusGenerateCodeDev")?.let {
            it.setDependsOn(it.dependsOn.map { it as Provider<*> }.filter { it.get() !is ProcessResources })
        }
    }

It's not perfect though, as it removing a ProcessResources task from a dependency list, in a submodule "app". It's where quarkus is in my project. Hope this will help others.

Edit: I came with a different approach for all who have a multimodule project with a Quarkus dependency spread all around:

project.afterEvaluate {
    getTasksByName("quarkusGenerateCode", true).forEach { task ->
        task.setDependsOn(task.dependsOn.map { it as Provider<Task> }.filter { it.get().name != "processResources" })
    }
    getTasksByName("quarkusGenerateCodeDev", true).forEach { task ->
        task.setDependsOn(task.dependsOn.map { it as Provider<Task> }.filter { it.get().name != "processResources" })
    }
}

It also is less save as it cast provider as Provider (but Kotlin says it Any type), so class cast may occur, though it didn't in my case. Then it compares name, finding the "processResources" by name.

raharrison commented 1 year ago

Still seeing this issue on 2.16.3.

@Augustyn is your workaround only applicable to multi-module projects? Trying something similar on a smaller project I'm getting a big mess of Gradle errors:

FAILURE: Build failed with an exception.

* What went wrong:
Some problems were found with the configuration of task ':compileTestKotlin' (type 'KotlinCompile').
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\grpc'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\avdl'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\avpr'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\avsc'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.
LazaroR94 commented 1 year ago

Still seeing this issue on 2.16.3.

@Augustyn is your workaround only applicable to multi-module projects? Trying something similar on a smaller project I'm getting a big mess of Gradle errors:

FAILURE: Build failed with an exception.

* What went wrong:
Some problems were found with the configuration of task ':compileTestKotlin' (type 'KotlinCompile').
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\grpc'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\avdl'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\avpr'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

    Please refer to https://docs.gradle.org/8.0.1/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: 'C:\projects\build\classes\java\quarkus-test-generated-sources\avsc'.

    Reason: Task ':compileTestKotlin' uses this output of task ':compileQuarkusTestGeneratedSourcesJava' 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 ':compileQuarkusTestGeneratedSourcesJava' as an input of ':compileTestKotlin'.
      2. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#dependsOn.
      3. Declare an explicit dependency on ':compileQuarkusTestGeneratedSourcesJava' from ':compileTestKotlin' using Task#mustRunAfter.

Yes, his code was applicable to multi-module projects but I believe he also shared a snippet for single module projects:

project.afterEvaluate {
    getTasksByName("quarkusGenerateCode", true).forEach { task ->
        task.setDependsOn(task.dependsOn.map { it as Provider<Task> }.filter { it.get().name != "processResources" })
    }
    getTasksByName("quarkusGenerateCodeDev", true).forEach { task ->
        task.setDependsOn(task.dependsOn.map { it as Provider<Task> }.filter { it.get().name != "processResources" })
    }
}
cogman commented 1 year ago

This works for Quarkus 3

project.afterEvaluate {
  getTasksByName("quarkusGenerateCode", true).forEach { task ->
    task.setDependsOn(task.dependsOn.filterIsInstance<Provider<Task>>().filter { it.get().name != "processResources" })
  }
  getTasksByName("quarkusGenerateCodeDev", true).forEach { task ->
    task.setDependsOn(task.dependsOn.filterIsInstance<Provider<Task>>().filter { it.get().name != "processResources" })
  }
}
Inori-Lover commented 8 months ago

it seem the problem fixed in quarkus@3.7.1 ? i update quarkus version and clean build script, found that after delete the code block and build still success🎇🎇

aloubyansky commented 8 months ago

I guess it might be a consequence of https://github.com/quarkusio/quarkus/pull/38249, which was also included in 3.7.0. Thanks for checking @Inori-Lover. I'll close this issue but please re-open anyone for whom it appears to be not fixed. Thanks.

FWest98 commented 8 months ago

This issue has not been resolved for me on 3.7.1.

Circular dependency between the following tasks:
:manager:kspKotlin
+--- :manager:quarkusGenerateCode
|    \--- :manager:processResources
|         \--- :manager:kspKotlin (*)
\--- :manager:quarkusGenerateCodeDev
     +--- :manager:processResources (*)
     \--- :manager:quarkusGenerateCode (*)
tanadeau commented 8 months ago

Seeing the same issue as @FWest98. Please re-open.

FWest98 commented 7 months ago

@aloubyansky To prevent this from going out of sight - the issue is not resolved yet.

laurentperez commented 6 months ago

FYI this is happening on latest quarkus 3.9.3 using https://github.com/Kotlin/dataframe/issues/657

@cogman comment fixes it.

aloubyansky commented 6 months ago

Ok, thanks for the info, I'm re-opening it.

aloubyansky commented 6 months ago

quarkus-reproducer.zip Reproducer updated to version 3.9.3