quarkusio / quarkus

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

Recompilation kotlin sources in dev mode should use compiler plugins #2811

Open jhorstmann opened 5 years ago

jhorstmann commented 5 years ago

Description Using quarkus 0.16.0 in a kotlin project, when hot reloading is triggered it seems like the kotlin files are recompiled without any kotlin compiler plugins. Consider a resource like the following

@Path("/greeting")
@ApplicationScoped
class GreetingResource @Inject constructor(val greetingService: GreetingService) { ... }

In order for this class to work correctly, it needs to not be final and to have a default constructor. Both can be achieved by configuring the maven kotlin-maven-plugin

<configuration>
    <compilerPlugins>
        <plugin>all-open</plugin>
        <plugin>no-arg</plugin>
    </compilerPlugins>
    <pluginOptions>
        <option>all-open:annotation=javax.enterprise.context.ApplicationScoped</option>
        <option>no-arg:annotation=javax.enterprise.context.ApplicationScoped</option>
    </pluginOptions>
</configuration>

And indeed the application is working when initially starting with

mvn compile quarkus:dev

But as soon as the source is modified the reload fails with

Caused by: javax.enterprise.inject.spi.DeploymentException: Found 2 deployment problems: 
[1] Normal scoped bean must not be final: CLASS bean [types=[GreetingResource, java.lang.Object], qualifiers=[@Default, @Any], target=GreetingResource]
[2] Normal scoped beans must declare a non-private constructor with no parameters: CLASS bean [types=[GreetingResource, java.lang.Object], qualifiers=[@Default, @Any], target=GreetingResource]

Implementation ideas Ideally the kotlin extension would reuse the configuration of the kotlin-maven-plugin from pom.xml. Alternatively there would need to be a separate configuration option for plugins of the quarkus-kotlin extension.

Issue #1157 is related, but this issue is actually more generic as there might be more classes or annotations that need special treatment by the kotlin compiler, which would then break after hot reloading.

geoand commented 5 years ago

@jhorstmann would you like to take a stab at it?

jhorstmann commented 5 years ago

@geoand I had a look into the code and can try to implement this. The rough idea would be

What I do not like about this approach is that there would be some kotlin compiler specific code in the DevMojo, but at the moment I can't think of another way. Parsing the compiler configuration would also duplicate some code from the kotlin-maven-plugin.

geoand commented 5 years ago

Perhaps @aloubyansky would care to comment on the proposed approach?

jhorstmann commented 5 years ago

Maybe the above outline is much more complex than needed. For most cases it would probably be enough to configure the no-arg and all-open plugins for any scope annotations. This should even work with the NormalScope meta annotation. I'm not using jpa at the moment, but I guess the no-arg would also be needed for any jpa entitites.

geoand commented 5 years ago

That sounds like a reasonable first step and best avoid all the complexity if we can

abreu-dev commented 4 years ago

Sorry for asking, but is there some workaround until this is fixed?

geoand commented 4 years ago

Not yet unfortunately. There where some Java compiler related changes that went into dev mode recently which might make tackling this a lot easier if someone wants to give it a shot.

stale[bot] commented 4 years ago

This issue/pullrequest has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

heri333 commented 4 years ago

I'm still very interested in a fix.

geoand commented 4 years ago

6030 should hopefully take care of the issue

geoand commented 4 years ago

Reopening as we still need to address the Gradle part in #6035

geoand commented 4 years ago

We have since decided that we will most likely go down the road of not requiring any Kotlin compiler plugins, but instead have Quarkus apply the necessary transformations. This will make the Kotlin experience frictionless no what matter what the build tool.

evanchooly commented 4 years ago

related #9856

emmanuelbernard commented 4 years ago

An idea from @aloubyansky is that we could look at Gradle list of tasks and run the compile one (instead of compiling ourselves)

evanchooly commented 4 years ago

jotting down notes:

when the dev plugins are launched from the build tool, context could be gathered and passed in to the plugin which can (hopefully) generically apply that context upon each rebuild/reload. this change would apply to both maven and gradle builds.

jamesward commented 2 years ago

What is the status of this? I just ran into this as described in: https://github.com/quarkusio/quarkus/issues/4266

geoand commented 2 years ago

@glefloch wasn't this fixed?

glefloch commented 2 years ago

Not really, it drops from my TODO list. In the current behaviour, we collect java arguments from Maven / Gradle mojo/task, and we forward it to the devmode context. It is also possible to set custom compiler arguments by configuration the dev mojo/task. We cannot really do the same things with kotlin as we don't depend on the Maven/Gradle plugin. I think we could introduce a new property in the dev mojo/task to set kotlin specific compiler arguments, this would avoid mixing java and kotlin compiler arguments in the same list (which does not work). WDYT of this @geoand, @aloubyansky ?

aloubyansky commented 2 years ago

We could handle it in the same way we handle the Java compiler config. I.e. we could check whether the user has specified kotilinCompilerArgs and if not, check whether corresponding Kotlin compiler plugin was configured and if so pull it from there?

StephenOTT commented 2 years ago

I am coming from: https://github.com/quarkusio/quarkus/issues/3591. Does this ongoing issue mean that @Valid does not work with Kotlin + Quarkus?

glefloch commented 2 years ago

@StephenOTT you can configure custom kotlin compiler arguments directly in the quarkus devmode mojo/task as documented here: https://quarkus.io/guides/kotlin#configuring-live-reload-compiler

This issue is about automatically collecting kotlin compiler arguments from kotlin compile mojo/task and this avoid to declare them both in the kotlin plugin and in the quarkus plugin.

mschorsch commented 1 year ago

This issue is about automatically collecting kotlin compiler arguments from kotlin compile mojo/task and this avoid to declare them both in the kotlin plugin and in the quarkus plugin.

@glefloch Have you any idea when this will be fixed?

mschorsch commented 10 months ago

I've found a workaround for Gradle: https://github.com/quarkusio/quarkus/issues/37109#issuecomment-1828352002