Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the Java Module System #2237

Closed
TheMrMilchmann opened this issue Sep 10, 2020 · 26 comments
Closed

Support the Java Module System #2237

TheMrMilchmann opened this issue Sep 10, 2020 · 26 comments

Comments

@TheMrMilchmann
Copy link

TheMrMilchmann commented Sep 10, 2020

I'm quoting directly from Kotlin/kotlinx.serialization#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
Copy link

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
Copy link

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

@bjonnh
Copy link

bjonnh commented Jan 16, 2021

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
Copy link

1fexd commented Apr 12, 2021

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

@abueide
Copy link

abueide commented May 8, 2021

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
Copy link
Contributor

lion7 commented May 8, 2021

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
Copy link

abueide commented May 8, 2021

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

@abueide
Copy link

abueide commented May 8, 2021

@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
Copy link
Contributor

lion7 commented May 8, 2021

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
Copy link

abueide commented May 8, 2021

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 {
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
Copy link

@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
Copy link

abueide commented Jul 11, 2021

@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
Copy link

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

@misaka19002
Copy link

misaka19002 commented Jul 12, 2021

@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
Copy link

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
Copy link

abueide commented Jul 12, 2021

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

santoszv pushed a commit to santoszv/kotlinx.coroutines that referenced this issue Aug 25, 2021
santoszv pushed a commit to santoszv/kotlinx.coroutines that referenced this issue Aug 25, 2021
santoszv pushed a commit to santoszv/kotlinx.coroutines that referenced this issue Aug 25, 2021
santoszv pushed a commit to santoszv/kotlinx.coroutines that referenced this issue Aug 25, 2021
santoszv pushed a commit to santoszv/kotlinx.coroutines that referenced this issue Aug 25, 2021
santoszv pushed a commit to santoszv/kotlinx.coroutines that referenced this issue Aug 26, 2021
@lion7
Copy link
Contributor

lion7 commented Sep 7, 2021

I created a PR which adds a dedicated module-info: Kotlin/kotlinx-datetime#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
Copy link

@lion7 did you make any headway with this?

@lion7
Copy link
Contributor

lion7 commented Nov 15, 2021

Not much, compilation fails because kotlinx.atomicfu is not a module.
So still waiting for Kotlin/kotlinx-atomicfu#201 to be merged.

@dorkbox
Copy link

dorkbox commented Dec 15, 2021

Any reason why #2901 has not been merged yet?

@durganmcbroom
Copy link

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

@dorkbox
Copy link

dorkbox commented May 17, 2022

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
Copy link

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

@lion7
Copy link
Contributor

lion7 commented May 19, 2022

I opened PR #3297 with full support for JPMS.
However, there is still an open issue with highlighting in IntelliJ IDEA that is kind of annoying...

@qwwdfsad
Copy link
Contributor

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
Copy link

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests