FasterXML / jackson-module-kotlin

Module that adds support for serialization/deserialization of Kotlin (http://kotlinlang.org) classes and data classes.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`NoSuchMethodError` for `com.fasterxml.jackson.module.kotlin.jacksonObjectMapper` after upgrading to 2.17.0

erdi opened this issue · comments

Search before asking

  • I searched in the issues and found nothing similar.
  • I searched in the issues of databind and other modules used and found nothing similar.
  • I have confirmed that the problem only occurs when using Kotlin.

Describe the bug

Calling jacksonObjectMapper() after importing com.fasterxml.jackson.module.kotlin.jacksonObjectMapper after upgrading to 2.17.0 throws

Caused by: java.lang.NoSuchMethodError: 'com.fasterxml.jackson.databind.ObjectMapper com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper$default(kotlin.jvm.functions.Function1, int, java.lang.Object)'

I believe that's related to 0dbe802. By the looks of things there's @JvmOverloads and the new arg is defaulted so this should just work, shouldn't it?

FWIW, I've also tried jacksonObjectMapper {} but got

Caused by: java.lang.NoSuchMethodError: 'com.fasterxml.jackson.databind.ObjectMapper com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper(kotlin.jvm.functions.Function1)'

To Reproduce

jacksonObjectMapper()

Expected behavior

No response

Versions

Kotlin: 1.9.20
Jackson-module-kotlin: 2.17.0
Jackson-databind: 2.17.0

Additional context

Not sure if that matters at all but the method in question is called from a field initializer in a companion object of a Gradle plugin implemented in kotlin.

FYI, ObjectMapper().registerModule(kotlinModule()) where kotlinModule is imported as com.fasterxml.jackson.module.kotlin.kotlinModule seems to work. kotlinModule does not carry @JvmOverloads so maybe that's related?

From the error message, it looks like you are running code compiled with 2.17 on a version less than 2.17.
Can you confirm which version is being used at runtime?
Or more information is needed.

I am having the same issue, I am almost certain our runtime versions are up-to-date and 2.17.

Please attach reproducible code.

Also, please check the com.fasterxml.jackson.module.kotlin.PackageVersion at runtime.
As mentioned above, the version of KotlinModule may have been overwritten at runtime.
If not, you should get 2.17.x.

Sorry I can't because it is company code.

However, I figured it out. Turns out my dependency tree was different in runtime and compile time somehow. The reason why I never realized this is that spring gradle plugin enforces a certain version of kotlin and it basically overrides everything that you specify in dependencies block. The only solution is to add the following,

configurations.all {
  resolutionStrategy.eachDependency { details ->
    if (details.requested.group.startsWith("com.fasterxml.jackson")) {
      details.useVersion("2.17.0")
    }
  }
}

Thanks for the verification.
Anyway, it seems that there is no problem with jackson-module-kotlin, so this issue is closed.

And fwtw, Jackson 2.17.1 was just released today. Probably won't change behavior here but just in case, upgrade strongly recommended (from 2.17.0).

@k163377
Did jackson intentionally make the compatibility loss from version 2.17?

Spring boot users often tend to use BOM to fix version.
(using dependency-management-plugin, gradle constraints, etc...)

The latest spring boot BOM is still jackson 2.15.4, so I think there are many cases in the JVM community where code compiled with 2.17.x is used in older jackson environments.

If there is a reason for the loss of compatibility, we should accept, but if the loss of compatibility is unintentional?

The reproduction code is available here.
https://github.com/be-hase/jackson-issue-202405

@be-hase
I was mistaken on this issue.
I assumed that Kotlin would prioritise the use of non-default functions, but unfortunately this is not the case.
https://youtrack.jetbrains.com/issue/KT-17300

As you say, this was unintentionally breaking compatibility.

I will look into fixing this over the weekend if possible.

Thanks.

I did a little research and it doesn't look like there is a good way to do it...
The only way might be to write the overload by hand.

https://medium.com/@yi.lu_55329/is-kotlin-default-arguments-a-solution-of-binary-backward-compatibility-374d2c9214d4

This will be fixed in the next release.

thanks :)