quarkus: Using Jackson support for Kotlin fails in native mode.
Describe the bug When using the Jackson Kotlin module with a Kotlin data class, it fails in native mode with the following:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.capitalone.polyglot.quarkus.model.Address` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
The example code is pretty straight forward:
@ApplicationScoped
class CustomObjectMapperConfig {
@Singleton
@Produces
fun objectMapper(): ObjectMapper {
return ObjectMapper().registerModule(KotlinModule())
}
}
data class Address(val addressLine1 : String, val addressLine2 : String, val addressLine3 : String, val addressLine4 : String, val city : String, val state : String, val country : String)
@Path("/deposits/tooling/validate-address")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
class AddressValidationResource {
@POST
fun validateAddress(address : Address) = address.copy(
addressLine1 = "${address.addressLine1} ${address.addressLine2} ${address.addressLine3} ${address.addressLine4}",
addressLine2 = "",
addressLine3 = "",
addressLine4 = "")
}
Expected behavior
(Describe the expected behavior clearly and concisely.)
If I run this in JVM mode, aka mvn compile quarkus:dev
, or as a runnable jar it works just fine.
Actual behavior (Describe the actual behavior clearly and concisely.)
To Reproduce Steps to reproduce the behavior: 1. 2. 3.
Configuration
# Add your application.properties here, if applicable.
Screenshots (If applicable, add screenshots to help explain your problem.)
Environment (please complete the following information):
- Output of
uname -a
orver
: - Output of
java -version
:
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-20190523183630.graal2.jdk8u-src-tar-gz-b03)
OpenJDK 64-Bit GraalVM CE 19.1.0 (build 25.212-b03-jvmci-20-b04, mixed mode)
- GraalVM version (if different from Java):
- Quarkus version or git rev:
<quarkus.version>0.21.2</quarkus.version>
Additional context (Add any other context about the problem here.) Related #3652
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 68 (47 by maintainers)
Commits related to this issue
- Ensure that Kotlin Data classes with default values work in native with JAX-RS Fixes: #3954 — committed to geoand/quarkus by geoand 5 years ago
- Ensure that Kotlin Data classes with default values work in native with JAX-RS Fixes: #3954 — committed to geoand/quarkus by geoand 5 years ago
- Ensure that Kotlin Data classes with default values work in native with JAX-RS Fixes: #3954 — committed to geoand/quarkus by geoand 5 years ago
- Ensure that Kotlin Data classes with default values work in native with JAX-RS Fixes: #3954 — committed to geoand/quarkus by geoand 5 years ago
- Merge pull request #6325 from geoand/#3954 Ensure that Kotlin Data classes with default values work in native with JAX-RS — committed to quarkusio/quarkus by gsmet 5 years ago
- Ensure that Kotlin Data classes with default values work in native with JAX-RS Fixes: #3954 — committed to gsmet/quarkus by geoand 5 years ago
I have tried a number of different configurations (slow testing cycle due to the 15minute native compile!). Upgrading to Quarkus 1.3.2, and GraalVM 20.x, did not initially make any difference. I then changed the POM to reflect your POM and it worked. I then individually started removing the POM configurations back to my original and the key (single) element that has made this work is in the Kotlin maven plugin configuration.
<javaParameters>true</javaParameters>
https://github.com/geoand/kotlin-jackson-demo/blob/cabe4f484a20c1b64332a4565060b49a3f1699c0/pom.xml#L120
So, as long as the latest POM creation through the maven archetypes generate the above setting (which appears to be the case), then this bug can be closed.
For anyone who is not creating a new project, they simply need to add the parameter to the “configuration” of the kotlin-maven-plugin, as linked to above.
Nobody is going to yell at anyone, we are as super friendly community 😃
The problem is that the behavior is different between JVM and native mode. With the no-arg plugin, in JVM the defaults are used which unfortunately is not the case in native mode.
@tellisnz-shift I also tried registering
Kotlin.Any
without success. I am knowledgeable of the Kotlin internals so I don’t have a path forward for the time being. I’ll try and contact the Kotlin folks and see if I get any infoThanks for confirming and looking into it. It certainly looks like it’s an issue with how Kotlin and Jackson interact.
So I will go ahead and close this since it doesn’t appear to be a Quarkus issue. If you feel that is not correct, please reopen and provide an update.
Thanks
For a short-term work-around the following working:
Thanks a lot for the thorough check @codemwnci!
Indeed the project generation now includes
<javaParameters>true</javaParameters>
: https://github.com/quarkusio/quarkus/blob/1.4.0.CR1/devtools/platform-descriptor-json/src/main/resources/templates/basic-rest/kotlin/pom.xml-template.ftl#L109 (seems like I added it in #6310)I’ll close this issue as per both our findings
@geoand yes, it’s the payload of a POST request.
Any news?
I was able to get around this problem by explicitly adding Jackson annotations. So, this code works in JVM mode but doesn’t in native mode
but this code works in both JVM and native modes and keeps the class immutable.
However, it pollutes my class and I expect to write code without any Jackson annotations as in the first example.
Kotlin: 1.3.71
So based on a suggestion from @gsmet when registering
kotlin.Metadata
from reflection, the process gets further but still fails. The latest error is:@odilonjk the problem you are seeing is different. In your case it is not a bug but because you are returning
Response
, it is necessary to use@RegisterForReflection
, see: https://quarkus.io/guides/rest-json#using-responseI was able to reproduce the problem. It doesn’t look like a regular Quarkus problem (since the class is registered for reflection), but more some kind of weird interop issue. I am guessing it will take a lot more digging than I can do at the moment, so let’s leave it open and I’ll take a look when I have som extra time.