forEach on a LinkedHashMap on Android (Samsung s4, s5 devices) + Kotlin + Multidex -> throws NoClassDefFoundError


#1

I just got an NoClassDefFoundError for trying to use a forEach on a LinkedHashMap with Android + Kotlin + Multidex on Samsung s4 and s5 devices.

Any idea what the problem is?


#2

If your lambda takes 2 parameters then it may be this problem: https://stackoverflow.com/questions/42869086/java-lang-noclassdeffounderror-inlinedforeachlambda1-in-kotlin/42869245


#3

Thanks for the reply Ilya!

Yes, it is probably related to something similar, my lambda is exactly as:

val links = linkedMapOf<LinkEntity, EntityRange>()
...
links.forEach { link, range -> url(link, range) }

I understand that this code cannot run on older version of Android, but I thought Kotlin would have solved this problem underneath. My biggest worry is now to create a custom static (Lint or otherwise) warning to force developers from using such a call when working with a LinkedHashMap, which is unfortunately not ideal.

Any suggestions?


#4

There’s already such a Lint warning (“Android | Lint | Correctness | Calling new methods on older versions”), however it didn’t work reliably until recently and only was fixed in coming Android Studio 3.2


#5

Oh my, it works on Android Studio 3.2, you’re right, thank you for the tip Ilya!

Call requires API level 24 (current min is 21): java.util.LinkedHashMap#forEach ...

However, it is crazy (and kind of sad) that this Lint check is not reliable in earlier versions of Android Studio. I am aware of Lint not working as expected from the command line and the UAST bug (supposedly fixed with 3.1), but I thought Android Studio 3 was working just fine from the IDE itself, very interesting…

THANK YOU


#6

One last question, if you’re so kind as to answer.

Since linkedMapOf() is kind of Kotlin (kotlin-stdlib), and Kotlin promises to solve this kind of language barrier versioning problem on Android, why does it fail on this instance?


#7

You are calling a method from the Java 8 stdlib. Kotlin cannot make that method exist. But I am sure there is an analogous function in the Kotlin stdlib.

So, Kotlin can fix the problem for you. You just need to call the correct function. As a general rule, don’t use the Java stdlib API for collections. Always use the analogous Kotlin API.


#8

Thanks for the respond, will keep that in mind.