quarkusio / quarkus

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

Live reload doesn't work for kotlin, gradle kotlin dsl project #37109

Open dodalovicgran opened 8 months ago

dodalovicgran commented 8 months ago

Describe the bug

i always have to restart the app whenever there's a change

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

No response

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

No response

Additional information

No response

quarkus-bot[bot] commented 8 months ago

/cc @evanchooly (kotlin), @geoand (kotlin), @glefloch, @quarkusio/devtools

aloubyansky commented 8 months ago

@dodalovicgran could you please provide a simple reproducer for your issue? Thanks.

dodalovicgran commented 8 months ago

❯ uname -a
Linux pop-os-dell-desktop 6.5.6-76060506-generic #202310061235~1697396945~22.04~9283e32 SMP PREEMPT_DYNAMIC Sun O x86_64 x86_64 x86_64 GNU/Linux
❯ java -version
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
❯ ./gradlew --version

------------------------------------------------------------
Gradle 8.3
------------------------------------------------------------

Build time:   2023-08-17 07:06:47 UTC
Revision:     8afbf24b469158b714b36e84c6f4d4976c86fcd5

Kotlin:       1.9.0
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          17.0.3 (Eclipse Adoptium 17.0.3+7)
OS:           Linux 6.5.6-76060506-generic amd64
dodalovicgran commented 8 months ago
plugins {
    kotlin("jvm") version "1.9.10"
    kotlin("plugin.allopen") version "1.9.10"
    id("io.quarkus")
}

repositories {
    mavenCentral()
    mavenLocal()
}

val quarkusPlatformGroupId: String by project
val quarkusPlatformArtifactId: String by project
val quarkusPlatformVersion: String by project

dependencies {
    implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
    implementation("io.quarkus:quarkus-kotlin")
    implementation("io.quarkus:quarkus-reactive-pg-client")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("io.quarkus:quarkus-arc")
    implementation("io.quarkus:quarkus-resteasy-reactive")
    implementation("io.quarkus:quarkus-mutiny")
    implementation("io.smallrye.reactive:mutiny-kotlin")
    implementation("io.quarkus:quarkus-config-yaml")
    implementation("io.quarkus:quarkus-resteasy-reactive-jackson")

    /* password encryption */
    implementation("io.quarkus:quarkus-elytron-security")
    /* /password encryption */

    /* flyway */
    implementation("io.quarkus:quarkus-flyway")
    implementation("io.quarkus:quarkus-jdbc-postgresql")
    /* /flyway */

    /* jwt */
    implementation("io.quarkus:quarkus-smallrye-jwt")
    implementation("io.quarkus:quarkus-smallrye-jwt-build")
    /* /jwt */

    /* logging */
    implementation("io.github.oshai:kotlin-logging-jvm:5.1.0")
    /* /logging */

    testImplementation("io.quarkus:quarkus-junit5")
    testImplementation("io.rest-assured:rest-assured")

    /* kotest */
    testImplementation("io.kotest:kotest-runner-junit5:5.8.0")
    testImplementation("io.kotest:kotest-assertions-core:5.8.0")
    /* /kotest */
}

group = "de.gransoftware.apps"
version = "1.0.0"

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

tasks.withType<Test> {
    systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager")
}

tasks.withType<Test>().configureEach {
    useJUnitPlatform()
}

allOpen {
    annotation("jakarta.ws.rs.Path")
    annotation("jakarta.enterprise.context.ApplicationScoped")
    annotation("io.quarkus.test.junit.QuarkusTest")
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString()
    kotlinOptions.javaParameters = true
}
dodalovicgran commented 8 months ago

i'm using reactive rest, with suspending functions

mschorsch commented 8 months ago

@dodalovicgran It would be much easier to reproduce your problem if you would provide a complete reproducer project. I'm sure someone will take a look at it and you'll get feedback much faster.

dodalovicgran commented 8 months ago

demo.zip

You can:

Let me know if this helps.

mschorsch commented 8 months ago

Thanks for the reproducer. In my opinion it is a bug.

The bug occurs when a resteasy reactive method is marked with suspend (Kotlin coroutines) and has the annotation @PermitAll at the same time. In addition, io.quarkus:quarkus-elytron-security must be on the classpath.

I have found the following (different) workarounds:

The error may also occur with Maven.

@geoand @aloubyansky Would you look at that?

michalvavrik commented 8 months ago

This sounds similar to https://github.com/quarkusio/quarkus/issues/35478.

mschorsch commented 8 months ago

As described in https://github.com/quarkusio/quarkus/issues/35478, the problem seems that the all-open kotlin compiler plugin ist not applied correctly when io.quarkus:quarkus-elytron-security is on the classpath.

geoand commented 8 months ago

I don't see what io.quarkus:quarkus-elytron-security could be doing to cause this problem...

geoand commented 8 months ago

But the general problem is indeed that when we detect a change, we are not correctly passing the necessary configuration to the Kotlin compiler.

mschorsch commented 8 months ago

Hope this will be fixed soon, we are migrating all our quarkus projects to Gradle and this issue sounds that it will cause additional problems.

mschorsch commented 8 months ago

similar issue https://github.com/quarkusio/quarkus/issues/29875

mschorsch commented 7 months ago

After a long fight with the kotlin compiler options, gradle and the quarkus-gradle-plugin i finally found a workaround, not pretty but it works:

dependencies {
   // ...

    // Important: Kotlin compiler plugin version must be the same as the Kotlin compiler version
    quarkusDev("org.jetbrains.kotlin:kotlin-allopen-compiler-plugin:1.9.10") 
}

// ...

tasks.quarkusDev {
    compilerOptions {
        compiler("kotlin").args(
            listOf(
                "-Xplugin=${configurations.quarkusDev.get().files.find { "kotlin-allopen-compiler-plugin" in it.name }}",
                "-P=plugin:org.jetbrains.kotlin.allopen:annotation=jakarta.ws.rs.Path",
                "-P=plugin:org.jetbrains.kotlin.allopen:annotation=jakarta.enterprise.context.ApplicationScoped",
                "-P=plugin:org.jetbrains.kotlin.allopen:annotation=jakarta.persistence.Entity",
                "-P=plugin:org.jetbrains.kotlin.allopen:annotation=io.quarkus.test.junit.QuarkusTest",
            )
        )
    }
}

Helpful links:

mschorsch commented 7 months ago

@geoand I think https://github.com/quarkusio/quarkus/issues/37109#issuecomment-1828352002 should be included in the Quarkus Kotlin documentation and in the code starts. This would make life much easier for kotlin users.

FredyH commented 7 months ago

While I think this is a good workaround, I don't think this is a satisfying overall fix because it requires a lot of manual configuration. I believe the problem is still Quarkus not passing the same arguments that the regular compiler gets to the dev compiler.

geoand commented 7 months ago

I believe the problem is still Quarkus not passing the same arguments that the regular compiler gets to the dev compiler.

Yes, that is the root cause