Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization Does not work with Jackson and Kotlin #413

Open
scprek opened this issue Dec 22, 2024 · 0 comments
Open

Deserialization Does not work with Jackson and Kotlin #413

scprek opened this issue Dec 22, 2024 · 0 comments

Comments

@scprek
Copy link

scprek commented Dec 22, 2024

I noticed all tests cast the body as a map. So maybe this is a new feature request?

Possible issues, but curious if the databind should be included by micronaut problem at least

zalando/problem#505

zalando/problem#485

zalando/problem#145

Expected Behavior

Without any additional dependencies, I'd expect http client calls with Problem type deserialization to work without Micronaut serde (I'm not sure if micronaut serde works either because switching to it broke too many things, will need to isolate)

Default Problem response

{"type":"about:blank","parameters":{},"status":404,"title":"Test Action does not exist"}

Constraint Violation Problem Response

{"violations":[{"field":"createScheduledAction.scheduledAction.scheduledTime","message":"must be a date in the present or in the future"}],"type":"https://zalando.github.io/problem/constraint-violation","status":400,"title":"Constraint Violation"}

Code

httpClient.toBlocking().exchange(HttpRequest.GET<Any>("v1/scheduled-action/${UUID.randomUUID()}"),
                argumentOf<Any>(), argumentOf<DefaultProblem>()
httpClient.toBlocking().exchange(HttpRequest.GET<Any>("v1/scheduled-action/${UUID.randomUUID()}"),
                argumentOf<Any>(), argumentOf<ConstraintViolationThrowableProblem>()

Note

Spring has ConstraintViolationProblemModule in addition to the ProblemModule()

Actual Behaviour

There are 2 Actual Behaviors based on an extra dependency added.

The Micronaut Object Mapper does not have ProblemModule() Registered. I had to include https://mvnrepository.com/artifact/org.zalando/jackson-datatype-problem/0.27.1

implementation("org.zalando:jackson-datatype-problem:0.27.1")

Default Problem response

{"type":"about:blank","parameters":{},"status":404,"title":"Test Action does not exist"}

Constraint Violation Problem Response

{"violations":[{"field":"createScheduledAction.scheduledAction.scheduledTime","message":"must be a date in the present or in the future"}],"type":"https://zalando.github.io/problem/constraint-violation","status":400,"title":"Constraint Violation"}

Without the Zalando Jackson DataTyp Dependency

Default Problem

08:40:06.404 [default-nioEventLoopGroup-1-3] DEBUG io.micronaut.http.client.netty.DefaultHttpClient - Error decoding HTTP error response body: Error decoding JSON stream for type [defaultProblem]: Cannot construct instance of `org.zalando.problem.StatusType` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 48]
io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [defaultProblem]: Cannot construct instance of `org.zalando.problem.StatusType` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 48]

ConstraintViolationThrowableProblem

07:16:24.457 [default-nioEventLoopGroup-1-3] DEBUG io.micronaut.http.client.netty.DefaultHttpClient - Error decoding HTTP error response body: Error decoding JSON stream for type [constraintViolationThrowableProblem]: Cannot construct instance of `org.zalando.problem.StatusType` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 4195] (through reference chain: io.micronaut.problem.violations.ConstraintViolationThrowableProblem["status"])
io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [constraintViolationThrowableProblem]: Cannot construct instance of `org.zalando.problem.StatusType` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 4195] (through reference chain: io.micronaut.problem.violations.ConstraintViolationThrowableProblem["status"])

With the Zalando Jackson Datatype Dependency

Default Problem

08:41:06.237 [io-executor-thread-1] ERROR io.micronaut.http.server.RouteExecutor - Unexpected error occurred: Error encoding object [io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace@1278937c] to JSON: Problem with definition of [AnnotedClass io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace]: Multiple 'any-getter' methods defined ([method io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace#getProperties()] vs [method io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace#getParameters()])
io.micronaut.http.codec.CodecException: Error encoding object [io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace@1278937c] to JSON: Problem with definition of [AnnotedClass io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace]: Multiple 'any-getter' methods defined ([method io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace#getProperties()] vs [method io.micronaut.problem.ProblemErrorResponseProcessor$IntrospectedThrowableProblemWithoutStacktrace#getParameters()])

ConstraintViolationThrowableProblem

08:41:52.372 [default-nioEventLoopGroup-1-3] DEBUG io.micronaut.http.client.netty.DefaultHttpClient - Error decoding HTTP error response body: Error decoding JSON stream for type [constraintViolationThrowableProblem]: Could not resolve type id 'https://zalando.github.io/problem/constraint-violation' as a subtype of `io.micronaut.problem.violations.ConstraintViolationThrowableProblem`: known type ids = [ConstraintViolationThrowableProblem]
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 147]
io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [constraintViolationThrowableProblem]: Could not resolve type id 'https://zalando.github.io/problem/constraint-violation' as a subtype of `io.micronaut.problem.violations.ConstraintViolationThrowableProblem`: known type ids = [ConstraintViolationThrowableProblem]
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 147]

Steps To Reproduce

Just so I don't have to parse out the body from the exception, I did this with application-test.yaml. But it does not affect the behavior, I get the same problem either way, this just seems nicer for tests as it feels more like REST assured.

micronaut:
  http:
    client:
      exception-on-error-status: false

Environment Information

  • Java 17
  • Kotlin 1.9.25
implementation(mn.micronaut.kotlin.extension)
implementation(mn.micronaut.jackson.databind)
implementation(mn.micronaut.problem.json)
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")

Example Application

No response

Version

4.7.2

@scprek scprek changed the title Deserialization Does not work with Jackson Deserialization Does not work with Jackson and Kotlin Dec 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant