diff --git a/README.md b/README.md index fac4a1a2e7..c11d97258a 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ suspend fun main() = coroutineScope { * [core/jvm](kotlinx-coroutines-core/jvm/) — additional core features available on Kotlin/JVM: * [Dispatchers.IO] dispatcher for blocking coroutines; * [Executor.asCoroutineDispatcher][asCoroutineDispatcher] extension, custom thread pools, and more. + * Integrations with `CompletableFuture` and JVM-specific extensions. * [core/js](kotlinx-coroutines-core/js/) — additional core features available on Kotlin/JS: * Integration with `Promise` via [Promise.await] and [promise] builder; * Integration with `Window` via [Window.asCoroutineDispatcher], etc. @@ -56,7 +57,7 @@ suspend fun main() = coroutineScope { * [ui](ui/README.md) — modules that provide coroutine dispatchers for various single-threaded UI libraries: * Android, JavaFX, and Swing. * [integration](integration/README.md) — modules that provide integration with various asynchronous callback- and future-based libraries: - * JDK8 [CompletionStage.await], Guava [ListenableFuture.await], and Google Play Services [Task.await]; + * Guava [ListenableFuture.await], and Google Play Services [Task.await]; * SLF4J MDC integration via [MDCContext]. ## Documentation @@ -259,9 +260,6 @@ See [Contributing Guidelines](CONTRIBUTING.md). - -[CompletionStage.await]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/await.html - diff --git a/build.gradle b/build.gradle index d5b231d969..4377240625 100644 --- a/build.gradle +++ b/build.gradle @@ -223,7 +223,9 @@ def core_docs_url = "https://kotlinlang.org/api/kotlinx.coroutines/$coreModule/" def core_docs_file = "$projectDir/kotlinx-coroutines-core/build/dokka/htmlPartial/package-list" apply plugin: "org.jetbrains.dokka" -configure(subprojects.findAll { !unpublished.contains(it.name) && it.name != coreModule }) { +configure(subprojects.findAll { !unpublished.contains(it.name) + && it.name != coreModule + && it.name != jdk8ObsoleteModule}) { if (it.name != 'kotlinx-coroutines-bom') { apply from: rootProject.file('gradle/dokka.gradle.kts') } @@ -232,7 +234,7 @@ configure(subprojects.findAll { !unpublished.contains(it.name) && it.name != cor configure(subprojects.findAll { !unpublished.contains(it.name) }) { if (it.name != "kotlinx-coroutines-bom") { - if (it.name != coreModule) { + if (it.name != coreModule && it.name != jdk8ObsoleteModule) { tasks.withType(DokkaTaskPartial.class) { dokkaSourceSets.configureEach { externalDocumentationLink { diff --git a/buildSrc/src/main/kotlin/Projects.kt b/buildSrc/src/main/kotlin/Projects.kt index af7098935d..2442c50934 100644 --- a/buildSrc/src/main/kotlin/Projects.kt +++ b/buildSrc/src/main/kotlin/Projects.kt @@ -8,6 +8,7 @@ fun Project.version(target: String): String = property("${target}_version") as String val coreModule = "kotlinx-coroutines-core" +val jdk8ObsoleteModule = "kotlinx-coroutines-jdk8" val testModule = "kotlinx-coroutines-test" val multiplatform = setOf(coreModule, testModule) diff --git a/buildSrc/src/main/kotlin/animalsniffer-conventions.gradle.kts b/buildSrc/src/main/kotlin/animalsniffer-conventions.gradle.kts index f00a0b315f..639245b6e5 100644 --- a/buildSrc/src/main/kotlin/animalsniffer-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/animalsniffer-conventions.gradle.kts @@ -17,6 +17,20 @@ configure(subprojects) { signature("net.sf.androidscents.signature:android-api-level-14:4.0_r4@signature") signature("org.codehaus.mojo.signature:java17:1.0@signature") } + + if (project.name == coreModule) { + // Specific files so nothing from core is accidentally skipped + tasks.withType().configureEach { + exclude("**/future/FutureKt*") + exclude("**/future/ContinuationHandler*") + exclude("**/future/CompletableFutureCoroutine*") + + exclude("**/stream/StreamKt*") + exclude("**/stream/StreamFlow*") + + exclude("**/time/TimeKt*") + } + } } } diff --git a/integration-testing/build.gradle b/integration-testing/build.gradle index 04be36fac9..f845816f34 100644 --- a/integration-testing/build.gradle +++ b/integration-testing/build.gradle @@ -22,8 +22,8 @@ dependencies { } sourceSets { - // Test that relies on Guava to reflectively check all Throwable subclasses in coroutines - withGuavaTest { + // An assortment of tests for behavior of the core coroutines module on JVM + jvmCoreTest { kotlin compileClasspath += sourceSets.test.runtimeClasspath runtimeClasspath += sourceSets.test.runtimeClasspath @@ -86,9 +86,9 @@ compileDebugAgentTestKotlin { } } -task withGuavaTest(type: Test) { +task jvmCoreTest(type: Test) { environment "version", coroutines_version - def sourceSet = sourceSets.withGuavaTest + def sourceSet = sourceSets.jvmCoreTest testClassesDirs = sourceSet.output.classesDirs classpath = sourceSet.runtimeClasspath } @@ -128,5 +128,5 @@ compileTestKotlin { } check { - dependsOn([withGuavaTest, debugDynamicAgentTest, mavenTest, debugAgentTest, coreAgentTest, 'smokeTest:build']) + dependsOn([jvmCoreTest, debugDynamicAgentTest, mavenTest, debugAgentTest, coreAgentTest, 'smokeTest:build']) } diff --git a/integration-testing/src/jvmCoreTest/kotlin/Jdk8InCoreIntegration.kt b/integration-testing/src/jvmCoreTest/kotlin/Jdk8InCoreIntegration.kt new file mode 100644 index 0000000000..91eef7e24b --- /dev/null +++ b/integration-testing/src/jvmCoreTest/kotlin/Jdk8InCoreIntegration.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2016-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ +package kotlinx.coroutines + +import kotlinx.coroutines.future.* +import org.junit.Test +import kotlin.test.* + +/* + * Integration test that ensures signatures from both the jdk8 and the core source sets of the kotlinx-coroutines-core subproject are used. + */ +class Jdk8InCoreIntegration { + + @Test + fun testFuture() = runBlocking { + val future = future { yield(); 42 } + future.whenComplete { r, _ -> assertEquals(42, r) } + assertEquals(42, future.await()) + } +} diff --git a/integration-testing/src/withGuavaTest/kotlin/ListAllCoroutineThrowableSubclassesTest.kt b/integration-testing/src/jvmCoreTest/kotlin/ListAllCoroutineThrowableSubclassesTest.kt similarity index 100% rename from integration-testing/src/withGuavaTest/kotlin/ListAllCoroutineThrowableSubclassesTest.kt rename to integration-testing/src/jvmCoreTest/kotlin/ListAllCoroutineThrowableSubclassesTest.kt diff --git a/integration/README.md b/integration/README.md index 89100179a8..54dd96bbc9 100644 --- a/integration/README.md +++ b/integration/README.md @@ -5,7 +5,6 @@ Module name below corresponds to the artifact name in Maven/Gradle. ## Modules -* [kotlinx-coroutines-jdk8](kotlinx-coroutines-jdk8/README.md) -- integration with JDK8 `CompletableFuture` (Android API level 24). * [kotlinx-coroutines-guava](kotlinx-coroutines-guava/README.md) -- integration with Guava [ListenableFuture](https://github.com/google/guava/wiki/ListenableFutureExplained). * [kotlinx-coroutines-slf4j](kotlinx-coroutines-slf4j/README.md) -- integration with SLF4J [MDC](https://logback.qos.ch/manual/mdc.html). * [kotlinx-coroutines-play-services](kotlinx-coroutines-play-services) -- integration with Google Play Services [Tasks API](https://developers.google.com/android/guides/tasks). diff --git a/integration/kotlinx-coroutines-jdk8/README.md b/integration/kotlinx-coroutines-jdk8/README.md index 321e293414..56e145fc4e 100644 --- a/integration/kotlinx-coroutines-jdk8/README.md +++ b/integration/kotlinx-coroutines-jdk8/README.md @@ -1,68 +1,3 @@ -# Module kotlinx-coroutines-jdk8 +# Stub module -Integration with JDK8 [CompletableFuture] (Android API level 24). - -Coroutine builders: - -| **Name** | **Result** | **Scope** | **Description** -| -------- | ------------------- | ---------------- | --------------- -| [future] | [CompletableFuture] | [CoroutineScope] | Returns a single value with the future result - -Extension functions: - -| **Name** | **Description** -| -------- | --------------- -| [CompletionStage.await][java.util.concurrent.CompletionStage.await] | Awaits for completion of the completion stage -| [CompletionStage.asDeferred][java.util.concurrent.CompletionStage.asDeferred] | Converts completion stage to an instance of [Deferred] -| [Deferred.asCompletableFuture][kotlinx.coroutines.Deferred.asCompletableFuture] | Converts a deferred value to the future - -## Example - -Given the following functions defined in some Java API: - -```java -public CompletableFuture loadImageAsync(String name); // starts async image loading -public Image combineImages(Image image1, Image image2); // synchronously combines two images using some algorithm -``` - -We can consume this API from Kotlin coroutine to load two images and combine then asynchronously. -The resulting function returns `CompletableFuture` for ease of use back from Java. - -```kotlin -fun combineImagesAsync(name1: String, name2: String): CompletableFuture = future { - val future1 = loadImageAsync(name1) // start loading first image - val future2 = loadImageAsync(name2) // start loading second image - combineImages(future1.await(), future2.await()) // wait for both, combine, and return result -} -``` - -Note that this module should be used only for integration with existing Java APIs based on `CompletableFuture`. -Writing pure-Kotlin code that uses `CompletableFuture` is highly not recommended, since the resulting APIs based -on the futures are quite error-prone. See the discussion on -[Asynchronous Programming Styles](https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md#asynchronous-programming-styles) -for details on general problems pertaining to any future-based API and keep in mind that `CompletableFuture` exposes -a _blocking_ method -[get](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html#get--) -that makes it especially bad choice for coroutine-based Kotlin code. - -# Package kotlinx.coroutines.future - -Integration with JDK8 [CompletableFuture] (Android API level 24). - -[CompletableFuture]: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html - - - - -[CoroutineScope]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/index.html -[Deferred]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html - - - - -[future]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/future.html -[java.util.concurrent.CompletionStage.await]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/await.html -[java.util.concurrent.CompletionStage.asDeferred]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/as-deferred.html -[kotlinx.coroutines.Deferred.asCompletableFuture]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/as-completable-future.html - - +Stub module for backwards compatibility. Since 1.7.0, this module was merged with core. diff --git a/integration/kotlinx-coroutines-jdk8/api/kotlinx-coroutines-jdk8.api b/integration/kotlinx-coroutines-jdk8/api/kotlinx-coroutines-jdk8.api index 4ee57845b2..e69de29bb2 100644 --- a/integration/kotlinx-coroutines-jdk8/api/kotlinx-coroutines-jdk8.api +++ b/integration/kotlinx-coroutines-jdk8/api/kotlinx-coroutines-jdk8.api @@ -1,22 +0,0 @@ -public final class kotlinx/coroutines/future/FutureKt { - public static final fun asCompletableFuture (Lkotlinx/coroutines/Deferred;)Ljava/util/concurrent/CompletableFuture; - public static final fun asCompletableFuture (Lkotlinx/coroutines/Job;)Ljava/util/concurrent/CompletableFuture; - public static final fun asDeferred (Ljava/util/concurrent/CompletionStage;)Lkotlinx/coroutines/Deferred; - public static final fun await (Ljava/util/concurrent/CompletionStage;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun future (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture; - public static synthetic fun future$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture; -} - -public final class kotlinx/coroutines/stream/StreamKt { - public static final fun consumeAsFlow (Ljava/util/stream/Stream;)Lkotlinx/coroutines/flow/Flow; -} - -public final class kotlinx/coroutines/time/TimeKt { - public static final fun debounce (Lkotlinx/coroutines/flow/Flow;Ljava/time/Duration;)Lkotlinx/coroutines/flow/Flow; - public static final fun delay (Ljava/time/Duration;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;Ljava/time/Duration;Lkotlin/jvm/functions/Function1;)V - public static final fun sample (Lkotlinx/coroutines/flow/Flow;Ljava/time/Duration;)Lkotlinx/coroutines/flow/Flow; - public static final fun withTimeout (Ljava/time/Duration;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static final fun withTimeoutOrNull (Ljava/time/Duration;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; -} - diff --git a/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api b/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api index ad04fb9c8e..3a2d08f428 100644 --- a/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api +++ b/kotlinx-coroutines-core/api/kotlinx-coroutines-core.api @@ -1176,6 +1176,15 @@ public final class kotlinx/coroutines/flow/internal/SendingCollector : kotlinx/c public fun emit (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } +public final class kotlinx/coroutines/future/FutureKt { + public static final fun asCompletableFuture (Lkotlinx/coroutines/Deferred;)Ljava/util/concurrent/CompletableFuture; + public static final fun asCompletableFuture (Lkotlinx/coroutines/Job;)Ljava/util/concurrent/CompletableFuture; + public static final fun asDeferred (Ljava/util/concurrent/CompletionStage;)Lkotlinx/coroutines/Deferred; + public static final fun await (Ljava/util/concurrent/CompletionStage;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun future (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;)Ljava/util/concurrent/CompletableFuture; + public static synthetic fun future$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture; +} + public final class kotlinx/coroutines/intrinsics/CancellableKt { public static final fun startCoroutineCancellable (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)V } @@ -1292,6 +1301,10 @@ public final class kotlinx/coroutines/selects/WhileSelectKt { public static final fun whileSelect (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } +public final class kotlinx/coroutines/stream/StreamKt { + public static final fun consumeAsFlow (Ljava/util/stream/Stream;)Lkotlinx/coroutines/flow/Flow; +} + public abstract interface class kotlinx/coroutines/sync/Mutex { public abstract fun getOnLock ()Lkotlinx/coroutines/selects/SelectClause2; public abstract fun holdsLock (Ljava/lang/Object;)Z @@ -1327,3 +1340,12 @@ public final class kotlinx/coroutines/sync/SemaphoreKt { public static final fun withPermit (Lkotlinx/coroutines/sync/Semaphore;Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } +public final class kotlinx/coroutines/time/TimeKt { + public static final fun debounce (Lkotlinx/coroutines/flow/Flow;Ljava/time/Duration;)Lkotlinx/coroutines/flow/Flow; + public static final fun delay (Ljava/time/Duration;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;Ljava/time/Duration;Lkotlin/jvm/functions/Function1;)V + public static final fun sample (Lkotlinx/coroutines/flow/Flow;Ljava/time/Duration;)Lkotlinx/coroutines/flow/Flow; + public static final fun withTimeout (Ljava/time/Duration;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun withTimeoutOrNull (Ljava/time/Duration;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + diff --git a/kotlinx-coroutines-core/build.gradle b/kotlinx-coroutines-core/build.gradle index a415aeec17..54883ff233 100644 --- a/kotlinx-coroutines-core/build.gradle +++ b/kotlinx-coroutines-core/build.gradle @@ -19,23 +19,50 @@ apply from: rootProject.file('gradle/publish.gradle') /* ========================================================================== Configure source sets structure for kotlinx-coroutines-core: - TARGETS SOURCE SETS - ------- ---------------------------------------------- + TARGETS SOURCE SETS + ------- ---------------------------------------------- js -----------------------------------------------------+ | V - jvm -------------------------------> concurrent ---> common - ^ - ios \ | - macos | ---> nativeDarwin ---> native --+ + jvmCore\ --------> jvm ---------> concurrent -------> common + jdk8 / ^ + | + ios \ | + macos | ---> nativeDarwin ---> native ---+ tvos | ^ watchos / | | linux \ ---> nativeOther -------+ mingw / - ========================================================================== */ + +Explanation of JVM source sets structure: + +The overall structure is just a hack to support the scenario we are interested in: + +* We would like to have two source-sets "core" and "jdk8" +* "jdk8" is allowed to use API from Java 8 and from "core" +* "core" is prohibited to use any API from "jdk8" +* It is okay to have tests in a single test source-set +* And we want to publish a **single** artifact kotlinx-coroutines-core.jar that contains classes from both source-sets +* Current limitation: only classes from "core" are checked with animal-sniffer + +For that, we have following compilations: +* jvmMain compilation: [jvmCoreMain, jdk8Main] +* jvmCore compilation: [commonMain] +* jdk8 compilation: [commonMain, jvmCoreMain] + +Theoretically, "jvmCore" could've been "jvmMain", it is not for technical reasons, +here is the explanation from Seb: + +""" +The jvmCore is theoretically not necessary. All code for jdk6 compatibility can be in jvmMain and jdk8 dependent code can be in jdk8Main. +Effectively there is no reason for ever putting code into jvmCoreMain. +However, when creating a new compilation, we have to take care of creating a defaultSourceSet. Without creating the jvmCoreMain source set, + the creation of the compilation fails. That is the only reason for this source set. +""" + ========================================================================== */ project.ext.sourceSetSuffixes = ["Main", "Test"] @@ -68,15 +95,12 @@ if (rootProject.ext.native_targets_enabled) { /* ========================================================================== */ + /* * All platform plugins and configuration magic happens here instead of build.gradle * because JMV-only projects depend on core, thus core should always be initialized before configuration. */ kotlin { - sourceSets.forEach { - SourceSetsKt.configureMultiplatform(it) - } - /* * Configure two test runs: * 1) New memory model, Main thread @@ -104,13 +128,32 @@ kotlin { } } + def jvmMain = sourceSets.jvmMain + def jvmCoreMain = sourceSets.create('jvmCoreMain') + def jdk8Main = sourceSets.create('jdk8Main') + jvmCoreMain.dependsOn(jvmMain) + jdk8Main.dependsOn(jvmMain) + + sourceSets.forEach { + SourceSetsKt.configureMultiplatform(it) + } + jvm { + def main = compilations.main + main.source(jvmCoreMain) + main.source(jdk8Main) + + /* Create compilation for jvmCore to prove that jvmMain does not rely on jdk8 */ + compilations.create('CoreMain') { + /* jvmCore is automatically matched as 'defaultSourceSet' for the compilation, due to its name */ + tasks.getByName('check').dependsOn(compileKotlinTaskProvider) + } + // For animal sniffer withJava() } } - configurations { configureKotlinJvmPlatform(kotlinCompilerPluginClasspath) } diff --git a/integration/kotlinx-coroutines-jdk8/src/future/Future.kt b/kotlinx-coroutines-core/jdk8/src/future/Future.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/src/future/Future.kt rename to kotlinx-coroutines-core/jdk8/src/future/Future.kt diff --git a/integration/kotlinx-coroutines-jdk8/src/stream/Stream.kt b/kotlinx-coroutines-core/jdk8/src/stream/Stream.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/src/stream/Stream.kt rename to kotlinx-coroutines-core/jdk8/src/stream/Stream.kt diff --git a/integration/kotlinx-coroutines-jdk8/src/time/Time.kt b/kotlinx-coroutines-core/jdk8/src/time/Time.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/src/time/Time.kt rename to kotlinx-coroutines-core/jdk8/src/time/Time.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/future/AsFutureTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/future/AsFutureTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/future/AsFutureTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/future/AsFutureTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/future/FutureAsDeferredUnhandledCompletionExceptionTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureAsDeferredUnhandledCompletionExceptionTest.kt similarity index 91% rename from integration/kotlinx-coroutines-jdk8/test/future/FutureAsDeferredUnhandledCompletionExceptionTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/future/FutureAsDeferredUnhandledCompletionExceptionTest.kt index bf810af7aa..9c9c97ecdf 100644 --- a/integration/kotlinx-coroutines-jdk8/test/future/FutureAsDeferredUnhandledCompletionExceptionTest.kt +++ b/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureAsDeferredUnhandledCompletionExceptionTest.kt @@ -1,8 +1,8 @@ /* - * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2016-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -package future +package kotlinx.coroutines.future import kotlinx.coroutines.* import kotlinx.coroutines.future.* diff --git a/integration/kotlinx-coroutines-jdk8/test/future/FutureExceptionsTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureExceptionsTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/future/FutureExceptionsTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/future/FutureExceptionsTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/stream/ConsumeAsFlowTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/stream/ConsumeAsFlowTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/stream/ConsumeAsFlowTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/stream/ConsumeAsFlowTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/time/DurationOverflowTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/time/DurationOverflowTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/time/DurationOverflowTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/time/DurationOverflowTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/time/FlowDebounceTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/time/FlowDebounceTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/time/FlowDebounceTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/time/FlowDebounceTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/time/FlowSampleTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/time/FlowSampleTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/time/FlowSampleTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/time/FlowSampleTest.kt diff --git a/integration/kotlinx-coroutines-jdk8/test/time/WithTimeoutTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/time/WithTimeoutTest.kt similarity index 100% rename from integration/kotlinx-coroutines-jdk8/test/time/WithTimeoutTest.kt rename to kotlinx-coroutines-core/jvm/test/jdk8/time/WithTimeoutTest.kt