Hi, guys. In our project, we use KMP with JVM and ...
# stdlib
a
Hi, guys. In our project, we use KMP with JVM and JS targets. After testing a migration to Kotlin 2.0, we encountered crashes when running the JS target. Our research led us to LinkedHashMap (MutableMap has the same behavior). It appears that after calling the Iterator#remove method, the entry's key and value fields can be set to null. Here’s a simple test case to reproduce:
Copy code
@Test
    fun test1() {
        val map = LinkedHashMap<String, Int>()
        val n = 3
        repeat(n) {
            map["$it"] = it
        }

        println(map)
        val iterator = map.iterator()
        var count = 0
        while (iterator.hasNext()) {
            val entry = iterator.next()
            iterator.remove()
            println("${entry.key}=${entry.value}")
//            assertEquals(count++, entry.value)
        }
    }
We got next results: JVM (on all versions):
Copy code
{0=0, 1=1, 2=2}
0=0
1=1
2=2
JS (Kotlin 1.9.24). Keys are null:
Copy code
{0=0, 1=1, 2=2}
null=0
null=1
null=2
JS (Kotlin 2.0.21). Keys and values are null:
Copy code
{0=0, 1=1, 2=2}
null=null
null=null
null=null
JS (Kotlin 2.1.0-RC). Throws exception when accessing entry after the remove method is called.
Copy code
ConcurrentModificationException: The backing map has been modified after this entry was obtained.
In version 2.1.0-RC , at least we encounter a crash on JS that could serve as a hint for developers. Do we mention about this somewhere in documentation? And should the behavior be consistent among platforms? I mean, it looks like we crash only on JS, but not on JVM. Is it expected behavior for now?
a
The new behavior is indeed as expected. We acknowledge that it differs from the JVM, but you should not rely on any of the observed behaviors. The documentation states:
Map.Entry
objects are valid only for the duration of the iteration; more formally, the behavior of a map entry is undefined if the backing map has been modified after the entry was returned by the iterator, except through the
setValue
operation on the map entry.
Do we mention about this somewhere in documentation?
As mentioned there are a few related public YouTrack issues where we have written about the change. Also, we will write about this behavior change in the compatibility guide document for the Kotlin 2.1.0
a
Hi! Thank you for provided information.