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

Cannot run compose desktop application using IDEA gutter #3123

Open
Walingar opened this issue May 3, 2023 · 34 comments
Open

Cannot run compose desktop application using IDEA gutter #3123

Walingar opened this issue May 3, 2023 · 34 comments
Labels
desktop external bug Bug in an external software other than CM/Skiko reproduced

Comments

@Walingar
Copy link
Collaborator

Walingar commented May 3, 2023

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

  1. Open image viewer example in IDEA
  2. 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.

@Walingar Walingar added bug Something isn't working submitted labels May 3, 2023
@Walingar
Copy link
Collaborator Author

Walingar commented May 3, 2023

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

@NorbertSandor
Copy link

NorbertSandor commented May 10, 2023

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

@NorbertSandor
Copy link

Besides, none of my "Kotlin application" run configurations work, not only the Compose/Desktop related ones :(

@sellmair
Copy link
Collaborator

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.

@AlexeyTsvetkov AlexeyTsvetkov added reproduced external bug Bug in an external software other than CM/Skiko and removed submitted bug Something isn't working labels May 12, 2023
@conradboehnke
Copy link

conradboehnke commented Jul 24, 2023

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 :)

@sellmair
Copy link
Collaborator

Please upgrade IntelliJ and Kotlin instead and report back if this works for you 👍

@shalva97
Copy link
Contributor

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

@sellmair
Copy link
Collaborator

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?

@dima-avdeev-jb
Copy link
Contributor

@Walingar Can you please check on your side and close this issue?

@shalva97
Copy link
Contributor

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

@maiatoday
Copy link

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.

@DarkAtra
Copy link

DarkAtra commented Aug 28, 2023

@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

@AlexeyTsvetkov
Copy link
Collaborator

@DarkAtra I'm not sure it is actually the same issue. Could you please provide some additional information?

  1. What OS do you use?
  2. What Kotlin Gradle plugin is used in the module where you are seeing the issue?
    Is it org.jetbrains.kotlin.jvm or org.jetbrains.kotlin.multiplatform?

@DarkAtra
Copy link

DarkAtra commented Aug 29, 2023

@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

@wwalkingg
Copy link

@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

Cradle sync firstly, then click the gutter in left of your app main function

@DarkAtra
Copy link

DarkAtra commented Aug 30, 2023

@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 used in previous versions?

@AlexeyTsvetkov
Copy link
Collaborator

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

@DarkAtra
Copy link

@AlexeyTsvetkov ty for the detailed explanation! i'll try using jvm as i primarily target windows.

@gandrewstone
Copy link

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: #3123 (comment) (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)
    }
}

@AlexeyTsvetkov
Copy link
Collaborator

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

@luangs7
Copy link

luangs7 commented Sep 12, 2023

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.

@wwalkingg
Copy link

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 ?

@luangs7
Copy link

luangs7 commented Sep 14, 2023

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

@pablichjenkov
Copy link

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

@sunny-chung
Copy link

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

@instabeejeongeun
Copy link

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.

@maiatoday
Copy link

ah no running ./gradlew run always works for me, it is only the green play button that doesn't

@nantoka69
Copy link

nantoka69 commented Nov 6, 2023

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.

@dima-avdeev-jb
Copy link
Contributor

@nantoka69 What Operatin system do you have?

@nantoka69
Copy link

Windows 10 Pro

@dima-avdeev-jb
Copy link
Contributor

@nantoka69 Can you please provide a minimal reproducible sample?
And we will try to check it on Windows too.

@sellmair
Copy link
Collaborator

There is still an issue on Android Studio; Root cause is that AS does not import Gradle task data and the execution relies on this data being present. The Kotlin Build Tools team is aware of this, right now.

https://youtrack.jetbrains.com/issue/KTIJ-27797/Android-Studio-Support-Multiplatform-jvm-run-carrier-task

@philburk
Copy link

philburk commented Feb 25, 2024

I had the same problem on Mac. I used the latest IDEA and a project downloaded from the Wizard.
I could not build it after an hours of work so I think the MultiPlatform feature is just not ready for prime time.

STEPS

  • upgraded from a 2022 IDEA CE to a more recent 2022 version.
  • downloaded 2023.3.4 to my MacBook.
IntelliJ IDEA 2023.3.4 (Community Edition)
Build #IC-233.14475.28, built on February 12, 2024
Runtime version: 17.0.10+1-b1087.17 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 14.2.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 16
Metal Rendering is ON
Kotlin: 233.14475.28-IJ
  • created a New project and clicked the "Multiplatform" line to go to the web page.
  • used the Wizard to create a project with Android, Desktop and Web.
  • drug the new project into ~/IdeaProjects/ and renamed the folder TestMultiPlatform.
  • opened the project in IDEA
  • selected the Desktop Main.kt
  • clicked the Green arrow to run the current file

EXPECTED
Hello world window.

ACTUAL
Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find libskiko-macos-x64.dylib.sha256, proper native dependency missing.

I tried going into Settings>>Build>>Compiler and change Kotlin compiler to 1.8.22.
But then I got errors related to Android SDK 34 license and it asked me to run "sdkmanager.bat", on a Mac!
So I switched back to the bundled 1.9.22 compiler.

I then went back to the Wizard and remove Android as a target and repeated the previous steps.
This time I got a bunch of errors related to not finding "KotlinProject".
Maybe I messed it up by renaming the project folder.

So I chnged the name to TestMultiPlatform in the Wizard.
Download a project for Desktop and Web.
Opened it in IDEA and now I am getting a ton of build errors like:

settings.gradle.kts:1:1: error: unresolved reference: rootProject
rootProject.name = "TestMultiPlatform"

settings.gradle.kts:1:13: error: variable expected
rootProject.name = "TestMultiPlatform"

I started over and created a Fresh project called KotlinProject.
I removed the old broken project from Recents.
Now I am back to the original libskiko error!

If I type: ./gradlew run
in the project folder then it builds and runs.

@philburk
Copy link

I tried the suggestion from nantoka69 above but it did not work using "desktop:run" on MacBook.
So I modified them slightly and the following worked.

  • Open "Edit Configurations ..."
  • Click on + to create a new configuration and choose Gradle not Kotlin
  • Enter ":composeApp:run" in the field labeled run
  • Click OK
  • Use green arrow to run the new configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
desktop external bug Bug in an external software other than CM/Skiko reproduced
Projects
None yet
Development

No branches or pull requests