diff --git a/kotlinx-coroutines-core/common/src/CoroutineExceptionHandler.kt b/kotlinx-coroutines-core/common/src/CoroutineExceptionHandler.kt index 49923a92e7..819f205b17 100644 --- a/kotlinx-coroutines-core/common/src/CoroutineExceptionHandler.kt +++ b/kotlinx-coroutines-core/common/src/CoroutineExceptionHandler.kt @@ -1,13 +1,19 @@ /* * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ - package kotlinx.coroutines import kotlin.coroutines.* +import kotlin.jvm.* internal expect fun handleCoroutineExceptionImpl(context: CoroutineContext, exception: Throwable) +/** + * JVM kludge: trigger loading of all the classes and service loading + * **before** any exception occur because it may be OOM, SOE or VerifyError + */ +internal expect fun initializeDefaultExceptionHandlers() + /** * Helper function for coroutine builder implementations to handle uncaught and unexpected exceptions in coroutines, * that could not be otherwise handled in a normal way through structured concurrency, saving them to a future, and diff --git a/kotlinx-coroutines-core/common/src/Job.kt b/kotlinx-coroutines-core/common/src/Job.kt index 31d90eeef0..085ef7e8af 100644 --- a/kotlinx-coroutines-core/common/src/Job.kt +++ b/kotlinx-coroutines-core/common/src/Job.kt @@ -113,7 +113,13 @@ public interface Job : CoroutineContext.Element { /** * Key for [Job] instance in the coroutine context. */ - public companion object Key : CoroutineContext.Key + public companion object Key : CoroutineContext.Key { + init { + // `Job` will necessarily be accessed early, so this is as good a place as any for the + // initialization logic that we want to happen as soon as possible + initializeDefaultExceptionHandlers() + } + } // ------------ state query ------------ diff --git a/kotlinx-coroutines-core/js/src/CoroutineExceptionHandlerImpl.kt b/kotlinx-coroutines-core/js/src/CoroutineExceptionHandlerImpl.kt index 54a65e10a6..a4d671dc65 100644 --- a/kotlinx-coroutines-core/js/src/CoroutineExceptionHandlerImpl.kt +++ b/kotlinx-coroutines-core/js/src/CoroutineExceptionHandlerImpl.kt @@ -6,6 +6,10 @@ package kotlinx.coroutines import kotlin.coroutines.* +internal actual fun initializeDefaultExceptionHandlers() { + // Do nothing +} + internal actual fun handleCoroutineExceptionImpl(context: CoroutineContext, exception: Throwable) { // log exception console.error(exception) diff --git a/kotlinx-coroutines-core/jvm/src/CoroutineExceptionHandlerImpl.kt b/kotlinx-coroutines-core/jvm/src/CoroutineExceptionHandlerImpl.kt index 6d06969293..4c8c81b8db 100644 --- a/kotlinx-coroutines-core/jvm/src/CoroutineExceptionHandlerImpl.kt +++ b/kotlinx-coroutines-core/jvm/src/CoroutineExceptionHandlerImpl.kt @@ -22,6 +22,12 @@ private val handlers: List = ServiceLoader.load( CoroutineExceptionHandler::class.java.classLoader ).iterator().asSequence().toList() +internal actual fun initializeDefaultExceptionHandlers() { + // Load CEH and handlers + CoroutineExceptionHandler +} + + internal actual fun handleCoroutineExceptionImpl(context: CoroutineContext, exception: Throwable) { // use additional extension handlers for (handler in handlers) { diff --git a/kotlinx-coroutines-core/native/src/CoroutineExceptionHandlerImpl.kt b/kotlinx-coroutines-core/native/src/CoroutineExceptionHandlerImpl.kt index b0aa86339a..7fedbd9fac 100644 --- a/kotlinx-coroutines-core/native/src/CoroutineExceptionHandlerImpl.kt +++ b/kotlinx-coroutines-core/native/src/CoroutineExceptionHandlerImpl.kt @@ -6,6 +6,10 @@ package kotlinx.coroutines import kotlin.coroutines.* +internal actual fun initializeDefaultExceptionHandlers() { + // Do nothing +} + internal actual fun handleCoroutineExceptionImpl(context: CoroutineContext, exception: Throwable) { // log exception exception.printStackTrace()