java.lang.NoClassDefFoundError: com.example.api.retrofit.AuthenticationInterceptor $ intercepte $ 1

Recientemente agregué retrofit2 a mi aplicación. Funciona bien en un Nexus 6P con Android 8.0, pero cuando probaba en un OnePlus One anterior, con Android 6.0.1, me encontré con un error:

java.lang.NoClassDefFoundError: com.example.api.retrofit.AuthenticationInterceptor$intercept$1 at com.example.api.retrofit.AuthenticationInterceptor.intercept(AuthenticationInterceptor.kt:21) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185) at okhttp3.RealCall.execute(RealCall.java:69) at retrofit2.OkHttpCall.execute(OkHttpCall.java:180) at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:91) at com.example.fragment.xx.XXFragment$onViewCreated$2.getItemsForConstraint(XXFragment.kt:53) at com.example.view.MyAutoCompleteTextView$Adapter$getFilter$1.performFiltering(MyAutoCompleteTextView.kt:114) at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.os.HandlerThread.run(HandlerThread.java:61) 

Aquí está mi código:

build.gradle

 buildscript { ext { okhttpVersion = '3.8.0' retrofitVersion = '2.3.0' } ... } 

app / build.gradle:

 compile "com.squareup.okhttp3:okhttp:$okhttpVersion" compile "com.squareup.okhttp3:logging-interceptor:$okhttpVersion" compile 'com.google.code.gson:gson:2.8.1' compile("com.squareup.retrofit2:retrofit:$retrofitVersion") { exclude module: 'okhttp' } compile "com.squareup.retrofit2:converter-gson:$retrofitVersion" 

Construyendo el service:

 OkHttpClient client = new OkHttpClient().newBuilder() .addInterceptor(new AuthenticationInterceptor(ctx)) .addInterceptor(new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(HOST + VERSION + "/") .client(client) .addConverterFactory(new EnvelopingConverter()) .addConverterFactory(GsonConverterFactory.create()) .build(); retrofitService = retrofit.create(ApiService.class); 

El interceptor:

 import android.content.Context import com.example.api.Api import com.example.controller.AuthManager import okhttp3.Interceptor import okhttp3.Response class AuthenticationInterceptor(val context: Context) : Interceptor { override fun intercept(chain: Interceptor.Chain?): Response? { var request = chain?.request() val headers = AuthManager.getAuthHeaders(context) if (request != null) { val requestBuilder = request.newBuilder() requestBuilder.addHeader(Api.HEADER_ACCEPT, Api.HEADER_APP_JSON) headers.forEach { key, value -> // this is line 21 requestBuilder.addHeader(key, value) } request = requestBuilder.build() } return chain?.proceed(request) } } 

No estoy seguro de cuál podría ser el problema? Alguien tiene alguna idea?

ACTUALIZAR:

Escribió el interceptor en Java y parece funcionar. ¿Por qué? Realmente me gustaría quedarme con Kotlin para este proyecto.

 public class AuthInterceptor implements Interceptor { private Context context; public AuthInterceptor(Context ctx) { context = ctx; } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Map<String, String> headers = AuthManager.getAuthHeaders(context); if (request != null) { Request.Builder requestBuilder = request.newBuilder(); requestBuilder.addHeader(Api.HEADER_ACCEPT, Api.HEADER_APP_JSON); for (String key : headers.keySet()) { requestBuilder.addHeader(key, headers.get(key)); } request = requestBuilder.build(); } return chain.proceed(request); } } 

Intenta deshabilitar la ejecución instantánea.

1 2 3

Después de un par de horas de debugging, descubrí lo que estaba pasando:

En mi file gradle también compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

Debido a esto, me permitió usar el siguiente código:

 headers.forEach { key, value -> // this is line 21 requestBuilder.addHeader(key, value) } 

Al descomstackr y mirar el código java, se verá así:

 e.forEach((BiConsumer)(new BiConsumer() { // $FF: synthetic method // $FF: bridge method public void accept(Object var1, Object var2) { this.accept((String)var1, (String)var2); } public final void accept(String key, String value) { requestBuilder.addHeader(key, value); } })); 

El problema aquí es que la class BiConsumer se agregó en API nivel 24 . Es por eso que funcionó en Android 8.0 (API nivel 26) y no funcionó en Android 6.0.1 (API nivel 23).

Por lo tanto, terminé usando un bucle regular for en lugar de forEach fui inicialmente.

El principal problema aquí es la exception: java.lang.NoClassDefFoundError: com.example.api.retrofit.AuthenticationInterceptor$intercept$1 . Si hubiera dicho java.lang.NoClassDefFoundError: java.util.function.BiConsumer , creo que hubiera sido mucho más fácil de depurar.

  • ¿Cómo saltarse los models proguard utilizados por retrofit2 que está en el package base?
  • Definir el tipo de retorno de modificación utilizando la interfaz en lugar de la class
  • El parámetro no tiene una coincidencia; SimpleXML
  • ¿Lee el valor de la anotación de la function de Kotlin usando la reflexión?
  • ¿Cómo correctamente serializar tal JSON por medio de GSON Android?
  • Obteniendo respuesta HTML / JSON original por error con Retrofit 2 y Kotlin
  • RxJava y Retrofit usando Kotlin
  • formatting @Query parameter - Retrofit 2
  • ¿Cómo crear una llamada asincrónica utilizando modificaciones y observaciones en Kotlin?
  • Retrofit + Deserialization GSON + Relación de reino
  • Dagger 2 no puede acceder a Retrofit