compose-multiplatform
compose-multiplatform copied to clipboard
Cannot run compose desktop application using IDEA gutter
Describe the bug When I have a multiplatform Compose project with desktop target, I try to run app with IDEA gutter icon and it fails in runtime with exceptions like:
Cannot find libskiko-macos-arm64.dylib.sha256, proper native dependency missing.
When use Gradle :run everything works fine but really slow, comparing with IDEA start.
If I use only jvm target, not multiplatform, starting from gutter works fine as well.
Affected platforms Select one of the platforms below:
- Desktop (in multiplatform setup)
Versions
- Kotlin version*: 1.8.20
- Compose Multiplatform version*: 1.4.0
- OS version: MacOS X
- OS architecture: arm64
- JDK (for desktop issues): corretto-17
To Reproduce
- Open image viewer example in IDEA
- Try to run desktop main from IDEA gutter
Result: it runs, but fails with exceptions like:
Cannot find libskiko-macos-arm64.dylib.sha256, proper native dependency missing.
Expected behavior Should work fine.
I investigated the issue a little bit and found that skiko loads libraries manually here
And Compose Gradle plugin provides all necessary resources, but when running from IDEA doesn't.
I don't know why it works fine with jvm only cases (without kotlin("mutliplatform") only kotlin("jvm")). Only noticed that with "jvm" plugin skiko-awt-runtime is provided as a runtime dependency but with "multiplatform" it is not
I've just run into this issue on Windows.
I used the "play" button to run the app which causes the error:
Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find skiko-windows-x64.dll.sha256, proper native dependency missing.
Executing the compose desktop/run Gradle task directly works.
The "play" button also works if I remove the
kotlin.mpp.import.enableKgpDependencyResolution=true
line from gradle.properties.
(But I cannot do that because my goal is to reevaluate Gradle included builds with multiplatform projects, which feature should theoretically work in Kotlin 1.8.20 but needs this setting.)
Related conversation: https://kotlinlang.slack.com/archives/C01D6HTPATV/p1683708168775229
Besides, none of my "Kotlin application" run configurations work, not only the Compose/Desktop related ones :(
Ok, I reviewed the current Situation and created the following issue on YouTrack: https://youtrack.jetbrains.com/issue/KT-58660/KGP-import-KotlinRunConfiguration-wont-be-able-to-infer-correct-runtime-classpath
Generally, I take this issue very seriously. The proposal will hopefully fix more issues with unreliable run-gutters. Please let me know if you have any objections or suggestions for improvement.
This may be a little late, but I had this issue too a while ago. So I looked into the documentation of Skiko itself and found out that they suggest manually importing it the following way (the "version" may differ):
val osName = System.getProperty("os.name")
val targetOs = when {
osName == "Mac OS X" -> "macos"
osName.startsWith("Win") -> "windows"
osName.startsWith("Linux") -> "linux"
else -> error("Unsupported OS: $osName")
}
val targetArch = when (val osArch = System.getProperty("os.arch")) {
"x86_64", "amd64" -> "x64"
"aarch64" -> "arm64"
else -> error("Unsupported arch: $osArch")
}
val version = "0.7.70" // or any more recent version
val target = "${targetOs}-${targetArch}"
sourceSets {
val jvmMain by getting {
dependencies {
implementation("org.jetbrains.skiko:skiko-awt-runtime-$target:$version")
implementation(compose.desktop.currentOs)
}
}
}
I simply put this into the following:
kotlin {}
but I think this also works when you just put it outside of it. But the implementation has to be in the 'dependencies {}' of course 😄 . This solution solved the problem perfectly for me. I also tried to change 'implementation(compose.desktop.currentOs)' to 'implementation(compose.desktop.macos_arm64)' but it didn't fix it for me. Hope this helps :)
Please upgrade IntelliJ and Kotlin instead and report back if this works for you 👍
Please upgrade IntelliJ and Kotlin instead and report back if this works for you 👍
I have spent lots of time on this, but at least it works with Kotlin 1.9.0, compose 1.5.0-beta01 and Intellij 2023.2
I am very glad to hear this! @AlexeyTsvetkov I think this issue is resolved; At least from IntelliJ and Kotlin side. What do you think about closing it?
@Walingar Can you please check on your side and close this issue?
One small thing to note, the old broken run configuration still persists(it has Kotlin icon), the new run config has Gradle icon and works. I was manually selecting it and was like not again...
I updated intellij and used Kotlin 1.9.0, compose 1.5.0-beta01 and Intellij 2023.2 on a desktop only compose project and I am still getting the missing skiko error. I fixed it using the manual import as described in the above comment So for me this is still an issue when I try to run from the gutter.
@AlexeyTsvetkov just ran into the same issue, can we reopen the ticket?
kotlin.version=1.9.0
compose.version=1.5.0
idea.version=IntelliJ IDEA 2023.2.1, Build #IU-232.9559.62, built on August 23, 2023
@DarkAtra I'm not sure it is actually the same issue. Could you please provide some additional information?
- What OS do you use?
- What Kotlin Gradle plugin is used in the module where you are seeing the issue?
Is it
org.jetbrains.kotlin.jvmororg.jetbrains.kotlin.multiplatform?
@AlexeyTsvetkov the exception reads:
Exception in thread "main" java.lang.ExceptionInInitializerError
at androidx.compose.ui.res.ImageResources_desktopKt.loadImageBitmap(ImageResources.desktop.kt:33)
[...]
Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find libskiko-macos-arm64.dylib.sha256, proper native dependency missing.
at org.jetbrains.skiko.Library.findAndLoad(Library.kt:105)
at org.jetbrains.skiko.Library.load(Library.kt:59)
I tried on both Windows 10 and MacOS 13.5.1 (22G90) on an Apple M2 Pro Chip and got the same error message (with different os and arch).
In my gradle setup, i use: kotlin("multiplatform") and id("org.jetbrains.compose") -> see: https://github.com/DarkAtra/bfme2-patcher/blob/compose-issue/updater/build.gradle.kts#L5-L6
Versions: https://github.com/DarkAtra/bfme2-patcher/blob/compose-issue/gradle.properties#L2-L3
@AlexeyTsvetkov the exception reads:
Exception in thread "main" java.lang.ExceptionInInitializerError at androidx.compose.ui.res.ImageResources_desktopKt.loadImageBitmap(ImageResources.desktop.kt:33) [...] Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find libskiko-macos-arm64.dylib.sha256, proper native dependency missing. at org.jetbrains.skiko.Library.findAndLoad(Library.kt:105) at org.jetbrains.skiko.Library.load(Library.kt:59)I tried on both
Windows 10andMacOS 13.5.1 (22G90)on an Apple M2 Pro Chip and got the same error message (with different os and arch).In my gradle setup, i use:
kotlin("multiplatform")andid("org.jetbrains.compose")-> see: https://github.com/DarkAtra/bfme2-patcher/blob/compose-issue/updater/build.gradle.kts#L5-L6Versions: https://github.com/DarkAtra/bfme2-patcher/blob/compose-issue/gradle.properties#L2-L3
Cradle sync firstly, then click the gutter in left of your app main function
@wwalkingg while that works, it does not allow setting a working directory via the run configuration anymore (this is a blocker for me). What is the reason for switching to gradle jvmRun instead of whatever compose was using in previous versions?
What is the reason for switching to gradle jvmRun instead of whatever compose was used in previous versions?
@DarkAtra we (Compose Multiplatform team) did not change anything in regards to this issue.
Some time ago, the Kotlin Multiplatform team had implemented a new, better, faster import. The new import did not consider that IntelliJ was bypassing Gradle when running applications, even if build/test actions are delegated to Gradle. When a user clicked the "run" icon in the gutter, IntelliJ would delegate the build itself, but then ran the application directly using run configuration settings and dependencies it resolved during the last import.
IntelliJ's default run mechanism is not very intuitive to both end users and Kotlin project developers. For example, even with the old KMP import, IntelliJ could discover a new runtime dependency only during re-import.
However, the new KMP import completely ignored runtime and runtimeOnly dependencies, because they are not needed for editing/refactoring/navigation and etc. At the same time, Compose's bindings to Skia (the native rendering library) are naturally runtime only dependencies:
- the native bindings have to be built for each platform separately;
- the bindings are quite big to put all platform DLLs into the same jar;
- and the rendering library should be considered an implementation detail anyway (we don't provide any compatibility guarantees for Skiko, all compatibility guarantees are for Compose public APIs only).
When the original issue with run from the gutter was uncovered, the new import was already enabled by default. To fix the issue, the Kotlin Multiplatform team has swiftly implemented a new run mechanism, which uses Gradle for both building and running code.
As a workaround, you can try to set the working directory in the build script:
tasks.configureEach {
if (name == "jvmRun") {
this as JavaExec
setWorkingDir(<A_DESIRED_BUILD_DIRECTORY>)
}
}
The old running mechanism still works for non-multiplatform modules. As long as your project does not target Android/iOS/WASM, you can try to use org.jetbrains.kotlin.jvm instead of org.jetbrains.kotlin.multiplatform Gradle plugin.
Also, feel free to send feedback to the Kotlin Multiplatform team directly by creating an issue at https://youtrack.jetbrains.com/issues/KTIJ
@AlexeyTsvetkov ty for the detailed explanation! i'll try using jvm as i primarily target windows.
I'm hitting this in multiplatform 1.9.0. I am doing multiplatform for both jvm and android (and other targets), so I had to roll my own jvm app jar because mp doesn't support jvm and android at the same time.
The workaround suggested here: https://github.com/JetBrains/compose-multiplatform/issues/3123#issuecomment-1647435023 (import a platform specific jar into the jvm project) works for me. But obviously its counter to the entire point of a JVM project which is to run on many platforms.
Any ideas about how/whether putting all the platform-specific jars into my app "fat" jar would work?
This is my jvm "fat jar creator" code:
/* Put all the dependent files into a single big jar */
tasks.register<Jar>("appJar") {
archiveClassifier.set("app")
manifest {
attributes["Main-Class"] = "my.class.path"
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
for (c in kotlin.targets.named("jvm").get().compilations)
{
val tmp = c.runtimeDependencyFiles
if (tmp != null)
{
// If its a jar blow the jar up and add the class files in that jar
from(tmp.filter { it.name.endsWith("jar") }.map { zipTree(it)})
}
from(c.output)
}
}
I'm hitting this in multiplatform 1.9.0. I am doing multiplatform for both jvm and android (and other targets), so I had to roll my own jvm app jar because mp doesn't support jvm and android at the same time.
@gandrewstone I don't understand, what mp doesn't support jvm and android at the same time means? Kotlin Multiplatform does support both JVM and Android targets in the same project. It's even possible to create a shared JVM source set between Desktop JVM and Android (there might be some quirks with doing that, but Compose Multiplatform actually uses that to avoid duplicating code between Android and Desktop JVM).
still happens on Mac M1 Compose version = 1.5.1 Kotlin version = 1.9.10 plugin = multiplatform
if downgrade Kotlin version to 1.8.10 and Compose version to 1.3.1 it works.
still happens on Mac M1
Compose version = 1.5.1
Kotlin version = 1.9.10
plugin = multiplatform
if downgrade Kotlin version to 1.8.10
and Compose version to 1.3.1 it works.
Try after gradle sync completely ?
still happens on Mac M1 Compose version = 1.5.1 Kotlin version = 1.9.10 plugin = multiplatform if downgrade Kotlin version to 1.8.10 and Compose version to 1.3.1 it works.
Try after gradle sync completely ?
yep, after a lot ones
@luangs7 try uninstalling the compose multiplatform plugin in AS/IJ and install it again. Or even better uninstall the plugin, install a more recent IDE version and install the plugin again. Also after uninstalling the plugin, make sure it is removed from the directory AS/IJ saves the plugins, just in case.
This issue appears after I upgrading my IDE from version 2022 to 2023, compose multiplatform from 1.3.0 to 1.5.2 and kotlin from 1.8.0 to 1.8.22. It disappears if I downgrade only kotlin back to 1.8.0.
Exception in thread "main" java.lang.ExceptionInInitializerError
at androidx.compose.ui.awt.WindowComposeBridge.<init>(WindowComposeBridge.desktop.kt:40)
at androidx.compose.ui.awt.ComposeWindowDelegate.<init>(ComposeWindowDelegate.desktop.kt:53)
at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:62)
at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:60)
at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:179)
at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:173)
at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:405)
at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:402)
at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:74)
at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:73)
at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1137)
at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828)
at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849)
at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1041)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:219)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find libskiko-macos-arm64.dylib.sha256, proper native dependency missing.
at org.jetbrains.skiko.Library.findAndLoad(Library.kt:105)
at org.jetbrains.skiko.Library.load(Library.kt:59)
at org.jetbrains.skiko.SkiaLayer.<clinit>(SkiaLayer.awt.kt:32)
... 32 more
I am using the Compose Multiplatform template generated by InteiiJ IDEA, and then manually updated the versions. The content of gradle.properties is as follow:
kotlin.code.style=official
kotlin.version=1.8.22
agp.version=7.3.0
compose.version=1.5.2
I also had the same issue but updating the versions like below and run command(./gradlew run) in the terminal fixed the issue.
kotlin.version=1.9.0 compose.version=1.5.0-beta01
Exception in thread "main" java.lang.ExceptionInInitializerError
...
Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find libskiko-macos-arm64.dylib.sha256, proper native dependency missing.
ah no running ./gradlew run always works for me, it is only the green play button that doesn't
The issue with the non-working green play button just appeared in my current Jetpack Compose Multiplatform project. It happened after I upgraded to the latest Kotlin plugin but as I import the compose libraries without version version numbers it could be as well that it was just something else that updated silently.
I use currently
- IntelliJ Community Edition 2023.1
- Kotlin 1.9
- Jetpack Compose 1.5.0
- Material3 1.1.1
After trying everything that I read here and in other sources about the problem I came up with the following solution:
- Open "Edit Configurations ..."
- Click on + to create a new configuration and choose Gradle not Kotlin
- Enter "desktop:run" in the field labeled run
- If you need command line options add --args="your command line options" after the gradle task name
That way I got at least a working green play button and can wait until some upgrades solve the problem.
@nantoka69 What Operatin system do you have?
Windows 10 Pro