square / retrofit

A type-safe HTTP client for Android and the JVM

Home Page:https://square.github.io/retrofit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

jackson-databind 2.17 not compatible with Android SDK 21-25

elvedincuskic-volvofinans opened this issue · comments

Issue

We're seeing issues and crashes on Sony/Samsung/Doro/Honor/Huawei devices running Android 7 - 7.1 (SDK 24-25) after updating retrofit dependencies to version 2.11.0 (previously 2.9.0).

I'm struggling to pinpoint the root cause but I found you've updated jackson-databind from 2.10.1 to 2.17 in the retrofit 2.10.0 release:

2.9.0: https://github.com/square/retrofit/blob/2.9.0/build.gradle#L29
2.10.0: https://github.com/square/retrofit/blob/2.10.0/gradle/libs.versions.toml#L23

According to this compatibility map I assume the jackson-databind 2.17 version is only compatible with Android SDK 26+:

https://github.com/FasterXML/jackson-databind/tree/2.17?tab=readme-ov-file#compatibility

This breaks the retrofit jackson-converter if you have minSdk set to SDK 21 (which retrofit should support according to the docs).

Setup

We're adding mixins when setting up our ObjectMapper before passing it during creation of the Retrofit instance. We also use the jackson kotlin module: https://github.com/FasterXML/jackson-module-kotlin.

This is briefly our setup:

val objectMapper = ObjectMapper().apply {
    setMixInResolver(...)
    registerModule(KotlinModule.Builder().build())
}

Retrofit.Builder().addConverterFactory(JacksonConverterFactory.create(objectMapper))

We use Java 17 in our project:

compileOptions {
  sourceCompatibility = JavaVersion.VERSION_17
  targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
  jvmTarget = JavaVersion.VERSION_17.toString()
}

and we're seeing the following crash/stacktrace in our production builds (for SDK 24-25 as previously mentioned):

Exception java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/BootstrapMethodError;
  at com.fasterxml.jackson.databind.util.ExceptionUtil.isFatal (ExceptionUtil.java:51)
  at com.fasterxml.jackson.databind.util.ExceptionUtil.rethrowIfFatal (ExceptionUtil.java:31)
  at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.<clinit> (JacksonAnnotationIntrospector.java:70)
  at com.fasterxml.jackson.databind.ObjectMapper.<clinit> (ObjectMapper.java:402)
  ...
Caused by java.lang.ClassNotFoundException:
  at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:56)
  at java.lang.ClassLoader.loadClass (ClassLoader.java:380)
  at java.lang.ClassLoader.loadClass (ClassLoader.java:312)

Any idea how to approach this besides reverting to retrofit 2.9.0 or forcing the version of the jackson-databind dependency?

I would force the version of Jackson to be lower.

Unfortunately we have no good options here. If we keep the Jackson dependency as low as possible, people complain about CVEs because they implicitly depend on our Jackson version instead of upgrading it to the latest. If we depend on the latest, we have may inadvertently break older Java or Android versions, as we obviously have done.

So I'm sorry that it's causing you a problem, but I think what's overall best for the project is to keep the dependencies up-to-date so that people get the latest security fixes and performance improvements.