camel-quarkus icon indicating copy to clipboard operation
camel-quarkus copied to clipboard

Kotlin DSL does not work in 3.2.0

Open squakez opened this issue 2 years ago • 3 comments

Bug description

I'm trying to execute a basic Kotlin DSL like:

// camel-k: language=kotlin

from("timer:kotlin?period=1000")
  .setBody()
    .simple("Hello Camel from \${routeId}")
  .log("\${body}")

Using Camel JBang (Camel 4 version), all is good:

$ camel run test.kts --logging-level DEBUG
...
2023-09-06 12:15:26.163 DEBUG 46242 --- [           main] sl.kotlin.KotlinRoutesBuilderLoader : Using JDK home inferred from java.home: /usr/lib/jvm/java-17-openjdk
2023-09-06 12:15:26.164 DEBUG 46242 --- [           main] sl.kotlin.KotlinRoutesBuilderLoader : Using JVM IR backend
2023-09-06 12:15:26.164 DEBUG 46242 --- [           main] sl.kotlin.KotlinRoutesBuilderLoader : Using JVM IR backend
2023-09-06 12:15:26.164 DEBUG 46242 --- [           main] sl.kotlin.KotlinRoutesBuilderLoader : Loading modules: [java.se, jdk.accessibility, jdk.attach, jdk.compiler, jdk.dynalink, jdk.httpserver, jdk.incubator.foreign, jdk.incubator.vector, jdk.jartool, jdk.javadoc, jdk.jconsole, jdk.jdi, jdk.jfr, jdk.jshell, jdk.jsobject, jdk.management, jdk.management.jfr, jdk.net, jdk.nio.mapmode, jdk.sctp, jdk.security.auth, jdk.security.jgss, jdk.unsupported, jdk.unsupported.desktop, jdk.xml.dom, kotlin.stdlib, kotlin.script.runtime, kotlin.reflect, java.base, java.compiler, java.datatransfer, java.desktop, java.xml, java.instrument, java.logging, java.management, java.management.rmi, java.rmi, java.naming, java.net.http, java.prefs, java.scripting, java.security.jgss, java.security.sasl, java.sql, java.transaction.xa, java.sql.rowset, java.xml.crypto, jdk.internal.jvmstat, jdk.management.agent, jdk.jdwp.agent, jdk.internal.ed, jdk.internal.le, jdk.internal.opt]
2023-09-06 12:15:26.164 DEBUG 46242 --- [           main] sl.kotlin.KotlinRoutesBuilderLoader : Loading modules: [java.se, jdk.accessibility, jdk.attach, jdk.compiler, jdk.dynalink, jdk.httpserver, jdk.incubator.foreign, jdk.incubator.vector, jdk.jartool, jdk.javadoc, jdk.jconsole, jdk.jdi, jdk.jfr, jdk.jshell, jdk.jsobject, jdk.management, jdk.management.jfr, jdk.net, jdk.nio.mapmode, jdk.sctp, jdk.security.auth, jdk.security.jgss, jdk.unsupported, jdk.unsupported.desktop, jdk.xml.dom, kotlin.stdlib, kotlin.script.runtime, kotlin.reflect, java.base, java.compiler, java.datatransfer, java.desktop, java.xml, java.instrument, java.logging, java.management, java.management.rmi, java.rmi, java.naming, java.net.http, java.prefs, java.scripting, java.security.jgss, java.security.sasl, java.sql, java.transaction.xa, java.sql.rowset, java.xml.crypto, jdk.internal.jvmstat, jdk.management.agent, jdk.jdwp.agent, jdk.internal.ed, jdk.internal.le, jdk.internal.opt]
2023-09-06 12:15:26.174 DEBUG 46242 --- [           main] .apache.camel.main.RoutesConfigurer : Adding templated routes into CamelContext from RoutesBuilder: Routes: [Route[From[timer:kotlin?period=1000] -> [SetBody[org.apache.camel.builder.ExpressionClause@68d6e126], Log[${body}]]]]
2023-09-06 12:15:26.175 DEBUG 46242 --- [           main] el.impl.engine.AbstractCamelContext : Adding templated routes from builder: Routes: [Route[From[timer:kotlin?period=1000] -> [SetBody[org.apache.camel.builder.ExpressionClause@68d6e126], Log[${body}]]]]
...

Packaging the application for Camel Quarkus and running in dev mode is good as well:

camel export --runtime=quarkus --gav=g:a:1.0.0 --dir /tmp/test
...
./mvnw quarkus:dev
...
2023-09-06 12:18:04,590 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (Quarkus Main Thread) Using JDK home inferred from java.home: /usr/lib/jvm/java-17-openjdk
2023-09-06 12:18:04,590 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (Quarkus Main Thread) Using JVM IR backend
2023-09-06 12:18:04,590 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (Quarkus Main Thread) Using JVM IR backend
2023-09-06 12:18:04,590 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (Quarkus Main Thread) Loading modules: [java.se, jdk.accessibility, jdk.attach, jdk.compiler, jdk.dynalink, jdk.httpserver, jdk.incubator.foreign, jdk.incubator.vector, jdk.jartool, jdk.javadoc, jdk.jconsole, jdk.jdi, jdk.jfr, jdk.jshell, jdk.jsobject, jdk.management, jdk.management.jfr, jdk.net, jdk.nio.mapmode, jdk.sctp, jdk.security.auth, jdk.security.jgss, jdk.unsupported, jdk.unsupported.desktop, jdk.xml.dom, kotlin.stdlib, kotlin.script.runtime, kotlin.reflect, java.base, java.compiler, java.datatransfer, java.desktop, java.xml, java.instrument, java.logging, java.management, java.management.rmi, java.rmi, java.naming, java.net.http, java.prefs, java.scripting, java.security.jgss, java.security.sasl, java.sql, java.transaction.xa, java.sql.rowset, java.xml.crypto, jdk.internal.jvmstat, jdk.management.agent, jdk.jdwp.agent, jdk.internal.ed, jdk.internal.le, jdk.internal.opt]

2023-09-06 12:18:04,590 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (Quarkus Main Thread) Loading modules: [java.se, jdk.accessibility, jdk.attach, jdk.compiler, jdk.dynalink, jdk.httpserver, jdk.incubator.foreign, jdk.incubator.vector, jdk.jartool, jdk.javadoc, jdk.jconsole, jdk.jdi, jdk.jfr, jdk.jshell, jdk.jsobject, jdk.management, jdk.management.jfr, jdk.net, jdk.nio.mapmode, jdk.sctp, jdk.security.auth, jdk.security.jgss, jdk.unsupported, jdk.unsupported.desktop, jdk.xml.dom, kotlin.stdlib, kotlin.script.runtime, kotlin.reflect, java.base, java.compiler, java.datatransfer, java.desktop, java.xml, java.instrument, java.logging, java.management, java.management.rmi, java.rmi, java.naming, java.net.http, java.prefs, java.scripting, java.security.jgss, java.security.sasl, java.sql, java.transaction.xa, java.sql.rowset, java.xml.crypto, jdk.internal.jvmstat, jdk.management.agent, jdk.jdwp.agent, jdk.internal.ed, jdk.internal.le, jdk.internal.opt]

2023-09-06 12:18:04,593 DEBUG [org.apa.cam.mai.RoutesConfigurer] (Quarkus Main Thread) Adding templated routes into CamelContext from RoutesBuilder: Routes: [Route[From[timer:kotlin?period=1000] -> [SetBody[org.apache.camel.builder.ExpressionClause@51ccf3d], Log[${body}]]]]
2023-09-06 12:18:04,593 DEBUG [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Adding templated routes from builder: Routes: [Route[From[timer:kotlin?period=1000] -> [SetBody[org.apache.camel.builder.ExpressionClause@51ccf3d], Log[${body}]]]]
...

However when I package the application and try to run the jar, it fails with the following error:

java -jar target/quarkus-app/quarkus-run.jar
...
2023-09-06 12:19:09,694 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (main) Using JDK home inferred from java.home: /usr/lib/jvm/java-17-openjdk
2023-09-06 12:19:09,694 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (main) Using JVM IR backend
2023-09-06 12:19:09,694 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (main) Using JVM IR backend
2023-09-06 12:19:09,694 DEBUG [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (main) Loading modules: [java.se, jdk.accessibility, jdk.attach, jdk.compiler, jdk.dynalink, jdk.httpserver, jdk.incubator.foreign, jdk.incubator.vector, jdk.jartool, jdk.javadoc, jdk.jconsole, jdk.jdi, jdk.jfr, jdk.jshell, jdk.jsobject, jdk.management, jdk.management.jfr, jdk.net, jdk.nio.mapmode, jdk.sctp, jdk.security.auth, jdk.security.jgss, jdk.unsupported, jdk.unsupported.desktop, jdk.xml.dom, kotlin.stdlib, kotlin.script.runtime, kotlin.reflect, java.base, java.compiler, java.datatransfer, java.desktop, java.xml, java.instrument, java.logging, java.management, java.management.rmi, java.rmi, java.naming, java.net.http, java.prefs, java.scripting, java.security.jgss, java.security.sasl, java.sql, java.transaction.xa, java.sql.rowset, java.xml.crypto, jdk.internal.jvmstat, jdk.management.agent, jdk.jdwp.agent, jdk.internal.ed, jdk.internal.le, jdk.internal.opt]
2023-09-06 12:19:09,694 ERROR [org.apa.cam.dsl.kot.KotlinRoutesBuilderLoader] (main) Module kotlin.script.runtime cannot be found in the module graph
2023-09-06 12:19:09,695 DEBUG [org.apa.cam.mai.RoutesConfigurer] (main) Adding templated routes into CamelContext from RoutesBuilder: Routes: []
2023-09-06 12:19:09,695 DEBUG [org.apa.cam.imp.eng.AbstractCamelContext] (main) Adding templated routes from builder: Routes: []
...

This behavior was not happening in CQ version 2. I tried to troubleshoot and check the kotlin dependencies but all seems good. I suspect that between the dev application and the prod application there is however something missing (the hints point to kotlin.script.runtime module, altough I can see the dependency where it's expected to be). I run out of ideas on how to continue the investigation. Any help is really appreciated.

squakez avatar Sep 06 '23 10:09 squakez

Could be related to this:

https://youtrack.jetbrains.com/issue/KT-57907

The warning goes away, if you hack the suggested -Xadd-modules=ALL-MODULE-PATH workaround into the compiler options here:

https://github.com/apache/camel/blob/main/dsl/camel-kotlin-dsl/src/main/kotlin/org/apache/camel/dsl/kotlin/KotlinCompilationConfiguration.kt

I'm no Kotlin expert, so not sure if that's an acceptable permanent solution or whether alternative workarounds are possible.

jamesnetherton avatar Sep 06 '23 12:09 jamesnetherton

Yeah, I had a look at that too. I am no Kotlin dev either, so I cannot really say. I think @lburgazzoli originally contributed to the DSL, hopefully he has some more expertise to share. What I cannot really understand is why it works when running as Camel Quarkus mvn quarkus:dev. IMO there is some dependency or configuration that we miss in the fatjar. I was not able to understand which are the differences between the 2 executions in order to make a diff and hopefully get the missing dependency.

In any case, if we run out of ideas I think we can temporarily patch adding the workaround as you're suggesting and monitor the dependency for any future fix.

squakez avatar Sep 06 '23 12:09 squakez

I've tried to include JVM settings locally but unfortunately they are not taken in consideration as the compiling is performed by the Camel dependency. The only way is to wait that https://github.com/apache/camel/pull/11378 is merged. In the while we cannot have Kotlin DSL correctly supported.

squakez avatar Sep 13 '23 08:09 squakez