Giter VIP home page Giter VIP logo

Comments (4)

EchoEllet avatar EchoEllet commented on July 24, 2024 1

A better workaround, to use Material 3 (excluding Material 2), Kotlin 2.0.0, Proguard 7.5.0, and Compose 1.6.10:

  1. Exclude Material 2 and include kotlinx-serialization-core:
implementation(compose.material3)
implementation(compose.desktop.currentOs) {
   exclude("org.jetbrains.compose.material")
}
// Explicitly include this is required to fix Proguard warnings coming from Kotlinx.DateTime
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.0")
  1. Update Compose Desktop Proguard settings to use Proguard 7.5.0 and include rules from a file:
compose.desktop {
    application {
        buildTypes.release.proguard {
            version.set("7.5.0")
            configurationFiles.from("proguard.pro")
        }
    }
}
  1. Create the file proguard.pro if doesn't exist, use the following rules:
-keep class androidx.compose.runtime.** { *; }
-keep class androidx.collection.** { *; }
-keep class androidx.lifecycle.** { *; }
-keep class androidx.compose.ui.text.platform.ReflectionUtil { *; }

# We're excluding Material 2 from the project as we're using Material 3
-dontwarn androidx.compose.material.**

# Kotlinx coroutines rules seems to be outdated with the latest version of Kotlin and Proguard
-keep class kotlinx.coroutines.** { *; }

This doesn't have the icon issue as the previous workaround does.

The Uber JAR on macOS Apple silicon:

image

The native application binary created with packageReleaseDmg

image

Note that there are Proguard notes that need to be solved.

from compose-multiplatform.

EchoEllet avatar EchoEllet commented on July 24, 2024

I managed to get it working with a workaround that's far from perfect and shouldn't be used in real production app

  1. First of all, try to reproduce the bug mentioned above
  2. Exclude Material module (Material 2) as mentioned in this #497 (comment) in #497 from all compose libraries:
implementation(compose.foundation) {
  exclude("org.jetbrains.compose.material")
}
implementation(compose.material3) {
  exclude("org.jetbrains.compose.material")
}
 implementation(compose.ui) {
    exclude("org.jetbrains.compose.material")
}
// ...

Or:

implementation(compose.desktop.currentOs) {
   exclude("org.jetbrains.compose.material")
}
  1. Create a new Proguard rules file and use it in the compose desktop module/source set
compose.desktop {
    application {
        // Your configurations

        buildTypes.release.proguard {
            configurationFiles.from(files("compose-desktop.pro"))
        }
    }
}

The name of the file is up to you, in my case, I created this project using (kmp.jetbrains.com), so I have to include this file in composeApp module (not inside desktopMain source set), the content will be something like

# TODO: Workaround to solve https://github.com/JetBrains/compose-multiplatform/issues/4883
-dontwarn androidx.compose.material.**
-keep class androidx.compose.material3.** { *; }
-ignorewarnings

This will keep all classes from Material 2 and ignore all the warnings from Material 2 and other warnings
4. Try to launch the release version of the app to use Proguard, a task like runReleaseDistributable, make sure to run it using your IDE as using ./gradlew runReleaseDistributable might use Java version 21 or above if installed and configured in the system path, the app will compile but you will get a runtime error if you use anything from Material 3 that depends on Material 2 which might be another issue, the code snippet:

import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

@Composable
fun App() {
    Button(onClick = {}) {
        Text(text = "Hi")
    }
}
  1. You should get the following error when launching the release version of the app:

image

This can be easily fixed by not excluding Material 2 from Material 3:

implementation(compose.material3)

or exclude Material 2 completely if used from Material 3 and only include the needed modules:

implementation(compose.material3) {
    // Explicitly exclude Material 2 completely from Material 3 in case Material 3 or any of its modules depends on the Material 2 module or any of its modules
    // At the moment, it seems to be only depending on material-ripple and material-icons-core modules
    exclude("org.jetbrains.compose.material")
}
// TODO: A workaround to include the needed modules after excluding the Material 2 module from Material 3 (see https://github.com/JetBrains/compose-multiplatform/issues/4883#issuecomment-2142445581) for more details
implementation("org.jetbrains.compose.material:material-ripple:${libs.versions.compose.get()}")
implementation("org.jetbrains.compose.material:material-icons-core:${libs.versions.compose.get()}")

The app works now
image

Noticed that the default Kotlin icon included in Compose desktop is not included and you will get this instead

image

I didn't investigate further about this

Another unrelated issue is that Material 3 depends on some Material 2 modules like the ripple effect and icons core

https://github.com/JetBrains/compose-multiplatform-core/blob/1694668f0d423babe94805bba603e087bd5ca943/compose/material3/material3/build.gradle#L104

This issue in https://github.com/JetBrains/compose-multiplatform-core
which is not in this repository

Additional details:

The binary bundle size that's created with packageReleaseDmg (requires Java installed)
after the workaround to use Material 3 with Proguard in the release version of the app

image

Before the workaround (Use Material 2)

image

The bundle size is around 6MB larger when using Material 3, I only used a Button and Text from Material 2 and Material 3, the size might not get much bigger when using more components from Material 3, this is another thing to look at but I'm not sure as I haven't looked into the source code in: https://github.com/JetBrains/compose-multiplatform-core

from compose-multiplatform.

syt0r avatar syt0r commented on July 24, 2024

I'm facing this issue too, is it going to be addressed in the next release? I think it should be mentioned in release notes too

from compose-multiplatform.

EchoEllet avatar EchoEllet commented on July 24, 2024

I'm facing this issue too, is it going to be addressed in the next release? I think it should be mentioned in release notes too

A workaround solution for now is to disable Proguard in the release or fix the issue with a workaround as mentioned above.

The workaround solution doesn't increase the size much. The difference is due to using Material 3

from compose-multiplatform.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.