Kotlin / kotlinx.coroutines

Library support for Kotlin coroutines
Apache License 2.0
13.06k stars 1.85k forks source link

Support the Java Module System #2237

Closed TheMrMilchmann closed 1 year ago

TheMrMilchmann commented 4 years ago

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.

makhocheung commented 4 years ago
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 ?

jobobby04 commented 4 years ago

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

bjonnh commented 3 years ago

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
1fexd commented 3 years ago

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

abueide commented 3 years ago

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 kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.BuildersKt.launch(Unknown Source) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47) at kotlinx.coroutines.core.jvm@1.5.0-RC/kotlinx.coroutines.BuildersKt.launch$default(Unknown Source) at com.abysl.harryplotter@1.0/com.abysl.harryplotter.data.JobProcess.reset(JobProcess.kt:41) at com.abysl.harryplotter@1.0/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 { 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.

lion7 commented 3 years ago

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.

abueide commented 3 years ago

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

abueide commented 3 years ago

@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

lion7 commented 3 years ago

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.

abueide commented 3 years ago

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](https://user-images.githubusercontent.com/19354425/117541207-678ca780-afd8-11eb-8c2b-2853be0f9a2e.png) 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 { 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
misaka19002 commented 3 years ago

@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

abueide commented 3 years ago

@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.

p-schneider commented 3 years ago

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

misaka19002 commented 3 years ago

@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ㄒ)/~~

p-schneider commented 3 years ago

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.

abueide commented 3 years ago

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

lion7 commented 3 years ago

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/

markslater commented 3 years ago

@lion7 did you make any headway with this?

lion7 commented 2 years ago

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.

dorkbox commented 2 years ago

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

durganmcbroom commented 2 years ago

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

dorkbox commented 2 years ago

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?

markslater commented 2 years ago

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

lion7 commented 2 years ago

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...

qwwdfsad commented 1 year ago

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

m-i-k-e-e commented 1 year ago

@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