compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

Support packaging uber/fat jar for all OS'es

Open igordmn opened this issue 3 years ago • 4 comments

Now we have only packageUberJarForCurrentOS which will only build jar that contain binary only for the current OS.

If Compose for Desktop will support packaging uber jar for all OS'es (jar that contains all native binaries, for each OS), it will simplify distribution of jar (we don't need multiple jar's for each OS, we can provide only one)

To do so, we need to:

  1. ~~modify skiko. We should add suffix with OS and arch to the binary file name ("skiko_win_x64.dll" instead of "skiko.dll", "skiko_macos_arm.dylib instead of "skiko.dylib", etc)~~

  2. add "org.jetbrains.compose.desktop:desktop-jvm-all" artifact to maven repo (it should contain all other artifacts "org.jetbrains.compose.desktop:desktop-jvm-windows-x64", "org.jetbrains.compose.desktop:desktop-jvm-macos-x64", etc)

  3. add "compose.desktop.all" alias for this new artifact in Compose for Desktop Gradle plugin.

  4. rename task packageUberJarForCurrentOS to packageUberJar (or just create a new task)

After that, users can define what binaries should exist in uber jar:

implementation(compose.desktop.currentOs)

or

implementation(compose.desktop.all)

or

implementation(compose.desktop.linux_x64)
implementation(compose.desktop.macos_x64)

igordmn avatar Mar 19 '21 07:03 igordmn

No need to modify Skiko - we already name is in proper format.

olonho avatar Mar 19 '21 08:03 olonho

compose.desktop.all is already existed in the past. We just need to return it

igordmn avatar Mar 19 '21 08:03 igordmn

Probably we shall be careful when creating such tasks, as it may unintentionally clutter native distribution for particular platform with unneeded Skia for other platforms.

olonho avatar Mar 19 '21 08:03 olonho

I've got the following setup to work:

  • multi-OS-target build
  • ProGuard
  • jpackage

I followed different routes, but ultimately, I skipped the compose desktop plugin entirely due to different shortcomings. The setup is now:

  • use a Gradle parameter to do different OS
  • use shadowjar to generate the uberjar(s)
  • obfuscate the uberjar with Proguard to generate a minified jar
  • run jpackage on the target OS host with GitHub actions to generate the target OS installer

Build file is here

MrStahlfelge avatar Jul 21 '22 07:07 MrStahlfelge

It seems that with Compose 1.2.2 the gradle task desktop:packageUberJarForCurrentOS despite its name packages skiko libraries of all OSes. The created jar files differ only by the file name, which includes the current OS name, but the files are identical and either can be started on either platform (tested with windows/linux).

mvlcek avatar Jan 06 '23 22:01 mvlcek

When I run the gradle task desktop:packageReleaseUberJarForCurrentOS on my MacOS arm64, I'm unable to run the jar on a Windows machine. I guess the problem is the same on a Linux machine.

Exception in thread "main" java.lang.ExceptionInInitializerError
        at androidx.compose.ui.awt.WindowComposeBridge.<init>(WindowComposeBridge.desktop.kt:43)
        at androidx.compose.ui.awt.ComposeWindowDelegate.<init>(ComposeWindowDelegate.desktop.kt:56)
        at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:64)
        at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:62)
        at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:180)
        at androidx.compose.ui.window.Window_desktopKt$Window$3.invoke(Window.desktop.kt:174)
        at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:407)
        at androidx.compose.ui.window.Window_desktopKt$Window$10.invoke(Window.desktop.kt:404)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:70)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2.invoke(AwtWindow.desktop.kt:69)
        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:108)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
        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 skiko-windows-x64.dll.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

Any idea?

cdongieux avatar Dec 20 '23 12:12 cdongieux

Oh ok, I had to modify this in my build.gradle.kts:

implementation(compose.desktop.currentOs)

to

    implementation(compose.desktop.macos_arm64)
    implementation(compose.desktop.windows_x64)
    implementation(compose.desktop.linux_x64)

Now it's working fine

cdongieux avatar Dec 20 '23 12:12 cdongieux