37 votes

Erreur java.lang.NoClassDefFoundError $$inlined$forEach$lambda$1 en Kotlin

Je travaille actuellement sur une application Android avec Kotlin en version 1.1.1.

Dans mon code, j'ai l'imbrication de plusieurs forEach afin de lire plusieurs MutableList y MutableMap .

Malheureusement, mon application se bloque avec la trace de pile suivante :

java.lang.NoClassDefFoundError : com.package.fragment.ReminderAddFragment$onRetrieveBusinessObjects$$inlined$forEach$lambda$1 à l'adresse com.package.fragment.ReminderAddFragment.onRetrieveBusinessObjects(ReminderAddFragment.kt:275) à l'adresse com.smartnsoft.droid4me.app.Droid4mizer.onRetrieveBusinessObjects(Droid4mizer.java:552) à l'adresse com.smartnsoft.droid4me.app.Droid4mizer.onRetrieveBusinessObjectsInternal(Droid4mizer.java:606) à l'adresse com.smartnsoft.droid4me.app.Droid4mizer.access$000(Droid4mizer.java:46) at com.smartnsoft.droid4me.app.Droid4mizer$1.run(Droid4mizer.java:197) à l'adresse java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) à l'adresse java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)

Voici le code

tutorialCategories.forEach { (_, _, _, _, _, tutorials) ->
  tutorials.forEach { tutorial ->
    if (tutorial.id == simpleReminderFromExtra.tutorialId)
    {
      //...
      val mapOfreminders = mutableMapOf<Int, MutableList<Reminder>>()
      val reminders = ReminderServices.getReminderByTutorialId(simpleReminderFromExtra.tutorialId)

      reminders.forEach { reminder ->
        //...
      }

      mapOfreminders.forEach { _, finalReminders ->
        //...

        finalReminders.forEach { reminder ->
          //...
        }

        //...
      }
    }
  }
}

Où :

  • tutorialCategories es un List ;
  • tutorials es un List ;
  • reminders es un List ;

La ligne 275 du code est mapOfreminders.forEach { _, finalReminders -> .

Dans le débogueur, je peux évaluer la fonction mapOfreminders variable et tout semble aller bien.

Si quelqu'un peut aider à résoudre ce problème !

0 votes

Pourriez-vous également préciser quelle version de Kotlin vous utilisez ?

0 votes

J'utilise Kotlin 1.1.1. J'ai modifié mon message.

0 votes

Pouvez-vous poster plus de contexte, comme vos inclusions et définitions de variables ? Pouvez-vous, d'une manière ou d'une autre, récupérer la version du code avant le crash ? Si vous obtenez une erreur no class-def, soit vous distribuez votre binaire sans les dépendances requises, soit vous utilisez une version différente de celle avec laquelle vous avez construit.

75voto

Ilya Points 8216

Après avoir lu l'article de Dan Lew poste il y a quelques jours, je suggérerai que cela peut être causé par l'utilisation de Map.forEach { k, v -> } de Java 8, qui peut ne pas être disponible dans le runtime Android.

Vous pouvez essayer d'utiliser une autre forEach avec le paramètre d'entrée unique qui provient de la bibliothèque standard de Kotlin :

mapOfreminders.forEach { (_, finalReminders) -> }

Ici, le parenthèses sont utilisés pour déstructurer le paramètre d'entrée en deux variables : la clé ignorée et le finalReminders valeur.

0 votes

Aussi, vous devez désactiver la course instantanée !

0 votes

Quelqu'un connaît-il un drapeau de compilation qui déclencherait une erreur ou au moins un avertissement lorsque la fonction BiConsumer de Java 8 est utilisée au lieu de celle de Kotlin ? Cela provoque des plantages dans mon application et je voudrais m'assurer que je n'utiliserai plus jamais la mauvaise version.

0 votes

@dvkch Que forEach de Java 8 devraient être capturés par linter dans Android Studio à partir de la version 3.2. Voir ce problème issuetracker.google.com/issues/80464232

13voto

zhangliang Points 221

J'ai rencontré ce problème java.lang.NoClassDefFoundError sur Android 6.0 et 6.0.1 en utilisant

Map.forEach {key ,value -> }

cet appel java 8 api.

Et puis, j'ai résolu ce problème en ajoutant des parenthèses au paramètre :

Map.forEach {(key ,value) -> }

cet appel à l'api kotlin

2voto

theThapa Points 51

Il semble que cette erreur particulière ne se produise pas sur tous les téléphones. J'ai rencontré un problème similaire avec le Samsung Galaxy S7, où l'application se plantait avec ClassNotFoundError. Cette solution fonctionne si nous voulons toujours utiliser le lambda. Sinon, en remplaçant le lambda par for ((key, value) in map) { ... } fonctionne également.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X