Open darren-bell-nanthealth opened 4 years ago
/cc @quarkusio/devtools
There is also no live-reload/hot-replace for Kotlin files in Maven projects.
In a mixed Java + Kotlin Quarkus application: if I change a Java source file then live-reload/hot-replace is performed. However, if I change a Kotlin source file then the change is not detected.
@belu Exactly. Even after the build and publishToMavenLocal tasks of Gradle been executed, Quarkus dev-mode don't hot reload this changes on the classpath, I tryed to debug "Thread.currentThread().getContextClassLoader()" and I found my Kotlin compiled class, but without the methods that I added before. This behaviour causes a runtime exception on Quarkus hot reload and the only way to solve is by restarting the process, wich is little annoying as I do a lot of changes on my external artifact.
I am using Quarkus 2.11 with JDK 17, my artifact is a Kotlin MPP Library but on the Quarkus project I using Java. It will be very good if the Quarkus hot-reload feature works with that setup.
@belu @fercomunello your use-case is different than the original issue. Please create a new one to track yours, mention me and if you can attach/reference a reproducer that will help a lot to fix it faster. Thanks!
@aloubyansky Done, thanks!
@belu If you are dealing with Kotlin non multiplatform code, just add this extension:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kotlin</artifactId>
</dependency>
You may be thinking that the solution for live-reload in dev mode between a Kotlin Multiplatform Library and Quarkus project is to just use Gradle modules, as multiplatform plugin exists only for Gradle, right? But it will not work, because the quarkus-kotlin extension is only able to compile for JVM environments, it is not a multiplatform compilant extension and is not propused to be one.
A quick explanation about Kotlin Multiplatform
Multiplatform compilation is based on expect and actual pattern, it's used when common module doesn't has a platform specific implementation built-in on the standard library, so it will expects to a specific platform module implementation, then the common code dynamically calls the right implementation during runtime. A great example is java.math.BigDecimal
class, it's a JVM specific implementation that doesn't built-in on the kotlin-stdlib, this class is only acessible by jvmMain module, so let's say that my common module needs to perform monetary operations, for that I can create a expect common class like commonMain/MonetaryAmount.kt
and 2 actual implementations, one actual class for JVM that will use java.math.BigDecimal
and another actual class for iOS that will use swift.NSDecimalNumber
to execute the operations like add, multiply, subtract, divide and so on ...
A quick explanation about how Quarkus live compilation works The Quarkus Core module has the CompilationProvider interface that is implemented by JavaCompilationProvider class, this custom compiler is built-in on every Quarkus project because it's essencial of course. But, for projects that uses Kotlin or have to mix Java and Kotlin between Maven or Gradle modules, it's necessary to add the quarkus-kotin extension, because this extension provides a KotlinCompilationProvider class that uses K2JVMCompiler internally, this compilation provider is registered by Quarkus using a ServiceLoader. Live reload works as expected in this case, even if the Quarkus application is a Java project and the shared library is written in Kotlin, or vice-versa.
A fix for this can be tricky: Quarkus Kotlin extension needs to somehow detects the Gradle modules (common, jvm) via a kotlin multiplatform plugin integration and then trigger multiplatform compilation before compile the application code.
@darren-bell-nanthealth This issue has been open for a long time and I don't know if it would make sense to mix multiplatform code with Quarkus, look at Ktor framework if you want to only use Kotlin features. Or, what makes more sense in my opinion is to publish the JAR of your multiplatform shared code in the local Maven repository and add it as a dependency on your Quarkus project: https://kotlinlang.org/docs/multiplatform-publish-lib.html
Also, take a look at #27242 issue that purpouse an enhancement/fix for reload the external JAR without need to restart Quarkus dev mode.
@aloubyansky Do you think this issue makes sense or is it better to close it for now?
We'll keep it open for now.
I think this issue still makes sense. Being able to share DTOs of your API with the clients of your API is a great benefit of Kotlin Multiplatform and can remove a lot of code duplication. Therefore, it would be great have this properly supported.
Describe the bug When I change the kotlin code in Kotlin Multiplatform plugin project, where quarkus is serving the backend, I would expect the quarkusDev gradle task to hot reload/deploy changes
Expected behavior Changes to the Kotlin code in the quarkus backend source to be compiled and redeployed
Actual behavior Nothing happens
To Reproduce Steps to reproduce the behavior:
Configuration
Screenshots (If applicable, add screenshots to help explain your problem.)
Environment (please complete the following information):
uname -a
orver
: Linux BFSWDBEL 4.19.104-microsoft-standard #1 SMP Wed Feb 19 06:37:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linuxjava -version
: openjdk version "11.0.6" 2020-01-14 OpenJDK Runtime Environment GraalVM CE 19.3.1 (build 11.0.6+9-jvmci-19.3-b07) OpenJDK 64-Bit Server VM GraalVM CE 19.3.1 (build 11.0.6+9-jvmci-19.3-b07, mixed mode, sharing)Build tool (ie. output of
mvnw --version
orgradlew --version
):Gradle 6.5.1
Build time: 2020-06-30 06:32:47 UTC Revision: 66bc713f7169626a7f0134bf452abde51550ea0a
Kotlin: 1.3.72 Groovy: 2.5.11 Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019 JVM: 11.0.6 (Oracle Corporation 11.0.6+9-jvmci-19.3-b07) OS: Linux 4.19.104-microsoft-standard amd64
Additional context (Add any other context about the problem here.)