micronaut-projects / micronaut-gradle-plugin

A Gradle Plugin for Micronaut
Apache License 2.0
66 stars 43 forks source link

If both ksp and kapt plugins are available, both also create bean definitions #801

Open braeluca opened 1 year ago

braeluca commented 1 year ago

Expected Behavior

If both ksp and kapt plugins are available, only one should be used.

Actual Behaviour

If both ksp and kapt plugins are available, both also create bean definitions, which is inefficient. It also leads to and exception when building the jar:

Execution failed for task ':runnerJar'.
Entry org/example/$ExampleController$Definition$Reference.class is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/8.2/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy for details.

However this can be resolved by specifying a duplicate strategy, but it is still inefficient. Sometimes kapt is also needed for other annotation processors.

Steps To Reproduce

  1. Create application with micronaut launch: mn create-app --build=gradle_kotlin --jdk=17 --lang=kotlin --test=junit com.example.demo
  2. Create any Bean or Controller
  3. Add kapt plugin to build.gradle.kts
  4. Run the assemble task

Environment Information

Example Application

https://github.com/braeluca/micronaut-kapt-ksp-demo

Version

4.0.3

sdelamo commented 12 months ago

We don't support both KAPT and KSP at the same time.

sdelamo commented 12 months ago

why do you want to use KAPT and KSP simultaneously?

braeluca commented 12 months ago

Some other annotation processor does not support ksp and probably never will and therefore i need to apply also the kapt plugin to use these.

graemerocher commented 12 months ago

If KSP is present then the inject-java module shouldn't be added to the kapt scope

graemerocher commented 12 months ago

check needs to be added here https://github.com/micronaut-projects/micronaut-gradle-plugin/blob/33d68598ae6f4750f1b08c58e0a3ff4359c0f63e/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautKotlinSupport.java#L110

melix commented 11 months ago

The issue is that we cannot know when the kapt or ksp plugins are applied. So even if we add a check, it can fail. There's more going on than just the annotation processor being added too.

braeluca commented 11 months ago

But correct me if i am wrong: To apply the dependencies for kapt or ksp scope, it must know, that kapt or ksp are added, right?

An alternative could be to disable kapt in the micronaut plugin via a config.

melix commented 11 months ago

Yes, we can do something when the KSP plugin is applied, or when the kapt plugin is applied. That's what we do. The thing is that we do it "twice" when both are applied. Disabling via configuration could be used too, but it's not that easy either because the flag could be set after the configuration was applied...

forresthopkinsa commented 3 months ago

Using kapt and ksp at the same time, I get a really non-obvious error: when I run the embedded server locally, it works correctly, but when I push a container to ECS with jib I get the error

More than 1 route matched the incoming request. The following routes matched /: GET - /, GET - /

Interestingly, even if I run the jib container locally, it works fine. Only get this error when running in ECS. Running a pretty minimal hello-world application.

Does Micronaut truly not support using both ksp and kapt at the same time? This would honestly be a significant issue, e.g. for using DynamoDB Object Mapper which currently only (source: micronaut-projects/micronaut-aws#1664) has third party support in Micronaut: com.agorapulse:micronaut-amazon-awssdk-dynamodb, which uses kapt

Even if that is the case, I feel like the behavior I'm seeing is especially cryptic and was extremely hard to troubleshoot. I have not found any other documentation anywhere that suggests that Micronaut does not support kapt and ksp simultaneously. If this is indeed the official policy, I would be happy to contribute docs updates.

graemerocher commented 3 months ago

it is not supported to use both at the same time no, feel free to contribute docs to clarify this