Skip to content

Commit

Permalink
fix(jvm): make job cancellation hashcode not fail after deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexRiedler committed Dec 4, 2024
1 parent 6c6df2b commit 8b8a0f8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
4 changes: 2 additions & 2 deletions kotlinx-coroutines-core/jvm/src/Exceptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ internal actual class JobCancellationException public actual constructor(
override fun equals(other: Any?): Boolean =
other === this ||
other is JobCancellationException && other.message == message && other.job == job && other.cause == cause
override fun hashCode(): Int =
(message!!.hashCode() * 31 + job.hashCode()) * 31 + (cause?.hashCode() ?: 0)
override fun hashCode(): Int = /* since job is transient it is indeed nullable after deserialization */
(message!!.hashCode() * 31 + (job?.hashCode() ?: 0)) * 31 + (cause?.hashCode() ?: 0)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,31 @@ class JobCancellationExceptionSerializerTest : TestBase() {
finish(4)
}
}

@Test
fun testHashCodeAfterDeserialization() = runTest {
try {
coroutineScope {
val job = launch {
hang {}
}
throw JobCancellationException(
message = "Job Cancelled",
job = job,
cause = null,
)
}
} catch (e: Throwable) {
val outputStream = ByteArrayOutputStream()
ObjectOutputStream(outputStream).use {
it.writeObject(e)
}
val deserializedException =
ObjectInputStream(outputStream.toByteArray().inputStream()).use {
it.readObject() as JobCancellationException
}
// verify hashCode does not fail even though Job is transient
assert(deserializedException.hashCode() != 0)
}
}
}

0 comments on commit 8b8a0f8

Please sign in to comment.