kotlinx.coroutines icon indicating copy to clipboard operation
kotlinx.coroutines copied to clipboard

Support the Java Module System

Open TheMrMilchmann opened this issue 3 years ago • 24 comments

I'm quoting directly from https://github.com/Kotlin/kotlinx.serialization/issues/940 because the same reasoning applies:

What is your use-case and why do you need this feature? As of Kotlin 1.4-M3, Java 9 module descriptors have been added to the standard library artifacts (KT-21266). It would be nice to see this also happen to libraries in the Kotlin ecosystem going forward as this would enable Kotlin JVM applications to benefit from modern JDK tools (such as jlink).

Describe the solution you'd like Ideally, an explicit descriptor would be added using the Multi-Release JAR mechanism (JEP 238) added in JDK 9 (just as it was done for the standard library).

Additionally,

  1. I'm currently working on a desktop application for which using the module system (with jlink and jpackage) is extremely handy and I would love to use kotlinx.coroutines without additional non-trivial build-system hacks.
  2. Publishing a library with an explicit module descriptor and with a dependency on kotlinx.coroutines is not possible because the latter does not have a stable module name.

A temporary (and fairly simple) solution for 2. would be providing stable Automatic-Module-Name entries.

TheMrMilchmann avatar Sep 10 '20 12:09 TheMrMilchmann

requires kotlinx.coroutines.core.jvm;
/Projects/java-demo/src/main/java/module-info.java:3: 错误: 找不到模块: kotlinx.coroutines.core.jvm
    requires kotlinx.coroutines.core.jvm;

I use kotlinx coroutines with jpms in my project. But I got error "cannot find module: kotlinx.coroutines.core.jvm". Does kotlinx coroutines not support jpms even using automatic module ?

makhocheung avatar Sep 14 '20 06:09 makhocheung

As a stop gap, for now add addExtraDependencies("kotlinx.coroutines") to your JLink gradle settings, it allows it to find coroutines

jobobby04 avatar Oct 11 '20 17:10 jobobby04

This stopgap doesn't work for me. First there is no "kotlinx.coroutines" I can add to module-info. I can get IntelliJ to accept kotlinx.coroutines.core.jvm … But trying to add any with addExtraDependencies doesn't help, it still says:

src/main/kotlin/module-info.java:6: error: module not found: kotlinx.coroutines.core.jvm
    requires kotlinx.coroutines.core.jvm;

or

src/main/kotlin/module-info.java:6: error: module not found: kotlinx.coroutines

bjonnh avatar Jan 16 '21 05:01 bjonnh

Hi, have there been any further developments regarding this issue?

1fexd avatar Apr 12 '21 07:04 1fexd

anyone know how to fix this?

Stacktrace Exception in thread "JavaFX Application Thread" java.lang.IllegalAccessError: class kotlin.coroutines.jvm.internal.DebugProbesKt (in module kotlin.stdlib) cannot access class kotlinx.coroutines.debug.internal.DebugProbesImpl (in module kotlinx.coroutines.core.jvm) because module kotlin.stdlib does not read module kotlinx.coroutines.core.jvm at kotlin.stdlib/kotlin.coroutines.jvm.internal.DebugProbesKt.probeCoroutineCreated(DebugProbes.kt:10) at kotlin.stdlib/kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted(IntrinsicsJvm.kt:122) at [email protected]/kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30) at [email protected]/kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25) at [email protected]/kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110) at [email protected]/kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126) at [email protected]/kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56) at [email protected]/kotlinx.coroutines.BuildersKt.launch(Unknown Source) at [email protected]/kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47) at [email protected]/kotlinx.coroutines.BuildersKt.launch$default(Unknown Source) at [email protected]/com.abysl.harryplotter.data.JobProcess.reset(JobProcess.kt:41) at [email protected]/com.abysl.harryplotter.controller.MainController.onStop(MainController.kt:174) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76) at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273) at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83) at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1859) at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1729) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.base/javafx.event.Event.fireEvent(Event.java:198) at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8889) at javafx.controls/javafx.scene.control.Button.fire(Button.java:203) at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208) at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274) at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.base/javafx.event.Event.fireEvent(Event.java:198) at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3856) at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1851) at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2584) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299) at java.base/java.security.AccessController.doPrivileged(AccessController.java:391) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446) at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556) at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942) at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174) at java.base/java.lang.Thread.run(Thread.java:831)
module-info.java

module com.abysl.harryplotter { requires kotlin.stdlib; requires kotlinx.coroutines.core.jvm; requires kotlinx.coroutines.javafx; requires kotlinx.serialization.core.jvm; requires kotlinx.serialization.json.jvm; requires java.prefs; requires javafx.controls; requires javafx.fxml; requires javafx.graphics; requires javafx.web; opens com.abysl.harryplotter.controller to javafx.fxml; opens com.abysl.harryplotter.data to kotlinx.serialization.core.jvm; exports com.abysl.harryplotter; }

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins { application kotlin("jvm") version "1.5.0" kotlin("plugin.serialization") version "1.5.0" id("org.openjfx.javafxplugin") version "0.0.10" id("org.beryx.jlink") version "2.23.8" }

group = "com.abysl" version = "1.0"

repositories { mavenCentral() }

dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.5.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0") }

application { applicationName = "Harry Plotter" mainClass.set("com.abysl.harryplotter.HarryPlotter") mainModule.set("com.abysl.harryplotter") }

javafx { version = "16" modules = listOf("javafx.base", "javafx.controls","javafx.fxml", "javafx.web") }

tasks.withType<KotlinCompile> { kotlinOptions { jvmTarget = "16" } }

val currentOs = org.gradle.internal.os.OperatingSystem.current()

jlink { options.set(listOf("--strip-debug", "--compress", "2", "--no-header-files", "--no-man-pages")) addExtraDependencies("javafx", "kotlinx.coroutines")

launcher {
    name = project.application.applicationName
    noConsole = true
}

jpackage {
    installerOptions = listOf("--resource-dir", "src/main/resources", "--vendor", "Abysl")
    if (currentOs.isWindows) {
        installerOptions = installerOptions + listOf("--win-per-user-install", "--win-dir-chooser", "--win-menu")
    } else if (currentOs.isLinux) {
    } else if (currentOs.isMacOsX) {
    }
    installerName = project.application.applicationName
    imageName = project.application.applicationName
    imageOptions = listOf("--icon", "src/main/resources/com/abysl/harryplotter/icons/snitch.ico")//, "--win-console")
    appVersion = project.version.toString()
}

}

It happens whenever I launch a coroutine, the program compiles and runs fine, but then throws and exception when the coroutine is called.

abueide avatar May 08 '21 00:05 abueide

It happens because you are using JDK 16. Previously, an illegal access was only logged once and your program would continue to run. Since JDK 16 the new default behavior is to throw an exception. See https://openjdk.java.net/jeps/396 for more details.

You can use this JVM argument as a workaround: --illegal-access=permit

Note that there are a lot of libraries that make use of this now considered illegal (reflective) access. Eventually they should all be fixed / refactored, but I have no idea how realistic that would be.

lion7 avatar May 08 '21 04:05 lion7

@lion7 thanks so much i've been banging my head against the wall trying to figure out what this meant.

abueide avatar May 08 '21 11:05 abueide

@lion7 weird so I enabled --illegal-access=permit through out all my gradle settings & configuration stuff where there was an xmx. running through gradle, its fine, there's no exceptions. its only when I run through intellij idea's gradle task does it throw an exception, even though in that run configuration i have it set.

image

abueide avatar May 08 '21 13:05 abueide

The VM options in your run configuration are passed to the Gradle JVM and not your application. You would probably have to configure it somewhere in your jpackage config, so that the packaged application will run with that parameter. Note that the run will fork a new JVM, so that one probably is still missing this JVM param.

lion7 avatar May 08 '21 13:05 lion7

Yeah I did do that, but the fact that its happening only in intellij says something weird is going on. I even set idea's own jvm parameters to have it. it even starts up the gradle task with 8:32:55 AM: Executing task 'run --illegal-access=permit'...

downgrading to kotlin 1.4.3 dependencies didn't work either

build.gradle.kts

image

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins { application kotlin("jvm") version "1.5.0" kotlin("plugin.serialization") version "1.5.0" id("org.openjfx.javafxplugin") version "0.0.10" id("org.beryx.jlink") version "2.23.8" }

group = "com.abysl" version = "1.0"

repositories { mavenCentral() }

dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.5.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0") }

val jvmOptions = listOf("-Xms256m", "-Xmx2048m", "--illegal-access=permit")

application { applicationName = "Harry Plotter" mainClass.set("com.abysl.harryplotter.HarryPlotter") mainModule.set("com.abysl.harryplotter") applicationDefaultJvmArgs = jvmOptions }

javafx { version = "16" modules = listOf("javafx.base", "javafx.controls","javafx.fxml", "javafx.web") }

tasks.withType<KotlinCompile> { kotlinOptions { jvmTarget = "11" } }

val currentOs = org.gradle.internal.os.OperatingSystem.current()

jlink { options.set(listOf("--strip-debug", "--compress", "2", "--no-header-files", "--no-man-pages")) addExtraDependencies("javafx")

launcher {
    name = project.application.applicationName
    noConsole = true
    jvmArgs = jvmOptions
}

jpackage {
    installerOptions = listOf("--resource-dir", "src/main/resources", "--vendor", "Abysl")
    if (currentOs.isWindows) {
        installerOptions = installerOptions + listOf("--win-per-user-install", "--win-dir-chooser", "--win-menu")
    } else if (currentOs.isLinux) {
    } else if (currentOs.isMacOsX) {
    }
    installerName = project.application.applicationName
    imageName = project.application.applicationName
    imageOptions = listOf("--icon", "src/main/resources/com/abysl/harryplotter/icons/snitch.ico")//, "--win-console")
    appVersion = project.version.toString()
}

}

gradle.properties

kotlin.code.style=official org.gradle.daemon=true org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx2048m -Xms256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 --illegal-access=permit

abueide avatar May 08 '21 13:05 abueide

@abueide Have u solved the problem? I have the same error .

Exception in thread "JavaFX Application Thread" java.lang.IllegalAccessError: class kotlin.coroutines.jvm.internal.DebugProbesKt (in module kotlin.stdlib) cannot access class kotlinx.coroutines.debug.internal.DebugProbesImpl (in module kotlinx.coroutines.core.jvm) because module kotlin.stdlib does not read module kotlinx.coroutines.core.jvm at

misaka19002 avatar Jul 11 '21 15:07 misaka19002

@lazyii no sadly i never figured it out. I ended up switching to badassruntime so I didn't have to deal with the modules system.

abueide avatar Jul 11 '21 19:07 abueide

The JVM parameter --add-reads kotlin.stdlib=kotlinx.coroutines.core.jvm should help with it.

p-schneider avatar Jul 11 '21 19:07 p-schneider

@p-schneider thx. config below: application { ....... applicationDefaultJvmArgs = listOf("--add-reads", "kotlin.stdlib=kotlinx.coroutines.core.jvm") } When i click debug, i can be executed. image

But when i click run, it still throws an exception. "module kotlin.stdlib does not read module kotlinx.coroutines.core.jvm ....." image

/(ㄒoㄒ)/~~

misaka19002 avatar Jul 12 '21 07:07 misaka19002

For some reason IntelliJ ignores the applicationDefaultJvmArgs setting in some cases when running via gradle. (See https://youtrack.jetbrains.com/issue/KTIJ-18424) So running gradle run from intellij would fail, but "gradlew run" from the console would succeed. In my project as a workaround I ended up adding an additional task to copy all modules/libs into a specific folder and then run it as a "Kotlin" type run configuration instead of gradle run.

p-schneider avatar Jul 12 '21 08:07 p-schneider

@p-schneider yeah this is exactly what I experienced as well

abueide avatar Jul 12 '21 15:07 abueide

~~I created a PR which adds a dedicated module-info: https://github.com/Kotlin/kotlinx-datetime/pull/135~~ Whoops, wrong repo / issue.. Anyway, I'm working on a PR to add JPMS support to kotlinx.coroutines. The biggest challenge is probably to add JPMS support to upstream libraries / dependencies first. My progress can be found here: https://github.com/lion7/kotlinx.coroutines/

lion7 avatar Sep 07 '21 05:09 lion7

@lion7 did you make any headway with this?

markslater avatar Nov 05 '21 21:11 markslater

Not much, compilation fails because kotlinx.atomicfu is not a module. So still waiting for https://github.com/Kotlin/kotlinx.atomicfu/pull/201 to be merged.

lion7 avatar Nov 15 '21 20:11 lion7

Any reason why https://github.com/Kotlin/kotlinx.coroutines/pull/2901 has not been merged yet?

dorkbox avatar Dec 15 '21 03:12 dorkbox

Im also having this issue! Would love to see it fixed

durganmcbroom avatar Mar 04 '22 03:03 durganmcbroom

It has been…. 5? years since the release of JPMS, and it has been 6 months since a fix has been posted.

Can SOMEONE please merge #2901?

“Hacking” JPMS for a project that, with quite literally 2 mouse clicks, could support JPMS is just frustrating beyond belief.

Maybe @qwwdfsad can help figure this out?

dorkbox avatar May 17 '22 17:05 dorkbox

FWIW, getting #2901 merged is certainly a step forwards, but @lion7 's blocked (stalled?) change for full JPMS support is the big win.

markslater avatar May 17 '22 20:05 markslater

I opened PR https://github.com/Kotlin/kotlinx.coroutines/pull/3297 with full support for JPMS. However, there is still an open issue with highlighting in IntelliJ IDEA that is kind of annoying...

lion7 avatar May 19 '22 14:05 lion7

I've published 1.7.0-jpms-preview to https://maven.pkg.jetbrains.space/public/p/kotlinx-coroutines/maven repository; if you are relying on JPMS in your project, consider checking it out before JPMS support is released

qwwdfsad avatar Feb 20 '23 13:02 qwwdfsad

@abueide Have u solved the problem? I have the same error .

Exception in thread "JavaFX Application Thread" java.lang.IllegalAccessError: class kotlin.coroutines.jvm.internal.DebugProbesKt (in module kotlin.stdlib) cannot access class kotlinx.coroutines.debug.internal.DebugProbesImpl (in module kotlinx.coroutines.core.jvm) because module kotlin.stdlib does not read module kotlinx.coroutines.core.jvm at

I recently had the same issue while debugging using IntelliJ, used this fix

https://youtrack.jetbrains.com/issue/KTIJ-15750/Debugger-doesnt-work-at-all-in-Java-projects-with-enabled-Kotlin-plugin-and-coroutine-debugger#focus=Comments-27-4923828.0-0

disable the coroutine agent in settings

m-i-k-e-e avatar Mar 03 '23 10:03 m-i-k-e-e