You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've tried and failed to create a bug using the retrofit bug template. It runs fine with MockWebServer but not in an actual Android app.
It runs fine in Android with GsonConverterFactory instead of JacksonConverterFactory.
It's also runs fine if the @Body is changed to a String instead of the Kotlin data class.
I tried with Retrofit 2.5.0, 2.4.0 and 2.2.0 and all had the same issue.
The crash on Android gives the following incomplete stack trace in logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.retrofitbodycrash, PID: 19561
java.lang.NoSuchMethodError: No virtual method getAnnotationsByType(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation; in class Ljava/lang/reflect/Method; or its super classes (declaration of 'java.lang.reflect.Method' appears in /system/framework/core-libart.jar)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.isRequiredByAnnotation(KotlinAnnotationIntrospector.kt:61)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.hasRequiredMarker(KotlinAnnotationIntrospector.kt:68)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.access$hasRequiredMarker(KotlinAnnotationIntrospector.kt:23)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector$hasRequiredMarker$1.invoke(KotlinAnnotationIntrospector.kt:33)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector$hasRequiredMarker$1.invoke(KotlinAnnotationIntrospector.kt:23)
at com.fasterxml.jackson.module.kotlin.ReflectionCache.javaMemberIsRequired(KotlinModule.kt:92)
at com.fasterxml.jackson.module.kotlin.KotlinAnnotationIntrospector.hasRequiredMarker(KotlinAnnotationIntrospector.kt:26)
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.hasRequiredMarker(AnnotationIntrospectorPair.java:307)
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.hasRequiredMarker(AnnotationIntrospectorPair.java:307)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder$4.withMember(POJOPropertyBuilder.java:655)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder$4.withMember(POJOPropertyBuilder.java:652)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.fromMemberAnnotations(POJOPropertyBuilder.java:1143)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder._findRequired(POJOPropertyBuilder.java:652)
at com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder.getMetadata(POJOPropertyBuilder.java:220)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._constructWriter(BeanSerializerFactory.java:771)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanProperties(BeanSerializerFactory.java:583)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.constructBeanSerializer(BeanSerializerFactory.java:368)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.findBeanSerializer(BeanSerializerFactory.java:279)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory._createSerializer2(BeanSerializerFactory.java:231)
at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:165)
at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:1388)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1356)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:551)
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:758)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.forRootType(ObjectWriter.java:1359)
at com.fasterxml.jackson.databind.ObjectWriter.<init>(ObjectWriter.java:112)
at com.fasterxml.jackson.databind.ObjectMapper._newWriter(ObjectMapper.java:689)
at com.fasterxml.jackson.databind.ObjectMapper.writerFor(ObjectMapper.java:3351)
at retrofit2.converter.jackson.JacksonConverterFactory.requestBodyConverter(JacksonConverterFactory.java:68)
at retrofit2.Retrofit.nextRequestBodyConverter(Retrofit.java:280)
at retrofit2.Retrofit.requestBodyConverter(Retrofit.java:260)
at retrofit2.RequestFactory$Builder.parseParameterAnnotation(RequestFactory.java:706)
at retrofit2.RequestFactory$Builder.parseParameter(RequestFactory.java:295)
at retrofit2.RequestFactory$Builder.build(RequestFactory.java:182)
at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:65)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMeth
The Code causing the crash. MainActivity modified in a new Android Kotlin AndroidX project:
package com.example.retrofitbodycrash
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import okhttp3.HttpUrl
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.Result
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.jackson.JacksonConverterFactory
import retrofit2.http.Body
import retrofit2.http.POST
class RetrofitBug {
@Rule
@JvmField
val server = MockWebServer()
internal interface Service {
@POST("/path")
fun search(@Body keyword: SignUpRequest): Single<Result<SignUpResponse>>
}
@Test
fun test() {
val example = createRetrofitService(Service::class.java, server.url("/"))
server.enqueue(
MockResponse()
.addHeader("Content-Type", "application/json")
.setBody("{\"first_name\": \"Mr\", \"last_name\": \"Test\", \"email\": \"[email protected]\", \"id\": 1}")
)
var response: SignUpResponse? = null
val disposable = getRxNetworkResult(example.search(
SignUpRequest(
first_name = "Mr",
last_name = "Test",
email = "[email protected]",
password = "password"
)))
.subscribeOn(Schedulers.trampoline())
.observeOn(Schedulers.trampoline())
.subscribe({
response = it
System.out.println("Success")
}, {
System.out.println("Error")
})
assertEquals("Mr", response?.first_name)
val recordedRequest = server.takeRequest()
assertEquals("/path", recordedRequest.getPath())
}
fun <T> createRetrofitService(
service: Class<T>,
baseUrl: HttpUrl? = HttpUrl.parse("https://fakeurl.test")
): T =
Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(JacksonConverterFactory.create(ignoreUnknownMapper()))
.baseUrl(baseUrl)
.build()
.create(service)
fun <T> getRxNetworkResult(single: Single<Result<T>>): Single<T> = single.map {
when {
it.isError -> throw NetworkError(
it.error() ?: Throwable("Unknown NetworkError")
)
it.response()?.isSuccessful == false -> throw ApiError(
it.response()?.code() ?: 500,
it.response()?.errorBody()?.string() ?: "Unknown ApiError"
)
else -> it.response()?.body() ?: throw ApiError(
500,
"Empty Body"
)
}
}
fun ignoreUnknownMapper(): ObjectMapper =
jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}
data class SignUpRequest(
val first_name: String,
val last_name: String,
val email: String,
val password: String
)
data class SignUpResponse(
val id: Int,
val first_name: String,
val last_name: String,
val email: String
)
The text was updated successfully, but these errors were encountered:
TTransmit
changed the title
Crash with @Body and JacksonConverterFactory: java.lang.NoSuchMethodError: No virtual method getAnnotationsByType
Crash with @Body and JacksonConverterFactory: java.lang.NoSuchMethodError: No virtual method getAnnotationsByType
Apr 10, 2019
TTransmit
changed the title
Crash with @Body and JacksonConverterFactory: java.lang.NoSuchMethodError: No virtual method getAnnotationsByType
Crash with @Body and JacksonConverterFactory: java.lang.NoSuchMethodError: No virtual method getAnnotationsByType
Apr 10, 2019
Method.getAnnotationsByType was added in Java 8 / Android API 26. The library which is calling the method (Jackson's Kotlin module I guess) likely only supports Java 8 or newer and thus will not work on prior versions of Java or Android prior to API 26.
You'll have to ask them if they're willing to support older versions. This isn't a problem with Retrofit itself.
What kind of issue is this?
get fixed. Here’s an example: https://gist.github.com/swankjesse/6608b4713ad80988cdc9
I've tried and failed to create a bug using the retrofit bug template. It runs fine with MockWebServer but not in an actual Android app.
It runs fine in Android with GsonConverterFactory instead of JacksonConverterFactory.
It's also runs fine if the
@Body
is changed to a String instead of the Kotlin data class.I tried with Retrofit 2.5.0, 2.4.0 and 2.2.0 and all had the same issue.
The crash on Android gives the following incomplete stack trace in logcat:
The Code causing the crash. MainActivity modified in a new Android Kotlin AndroidX project:
app build.gradle:
Zipped version of the sample project
RetrofitBodyCrash.zip
The text was updated successfully, but these errors were encountered: