-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix runRelease
task when navigation and obfuscate.set(true)
are used
#5384
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
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Fixes https://youtrack.jetbrains.com/issue/CMP-8050/Desktop-runRelease-crash-when-upgrade-to-CMP-1.8.0-rc01 Navigation uses `@InternalSerializationApi kotlinx.serialization.serializer` inside which can be not covered by [the default](https://github.com/Kotlin/kotlinx.serialization/blob/4667a18/rules/common.pro) rules. Without obfuscation we have class `LoginRoute$Companion.class`: ``` package fsd; import kotlin.Metadata; import kotlinx.serialization.KSerializer; @metadata(mv = {2, 2, 0}, k = 1, xi = 48, d1 = {"\000\026\n\002\030\002\n\002\020\000\n\002\b\003\n\002\030\002\n\002\030\002\n\000\b\003\030\0002\0020\001B\t\b\002\006\004\b\002\020\003J\f\020\004\032\b\022\004\022\0020\0060\005\006\007"}, d2 = {"Lfsd/LoginRoute$Companion;", "", "<init>", "()V", "serializer", "Lkotlinx/serialization/KSerializer;", "Lfsd/LoginRoute;", "composeApp"}) public final class Companion { private Companion() {} public final KSerializer<LoginRoute> serializer() { return (KSerializer<LoginRoute>)LoginRoute.$serializer.INSTANCE; } } ``` which is covered by the existing rule (`-keepclassmembers class <2>$<3>` filters `LoginRoute$Companion`): ``` -if @kotlinx.serialization.Serializable class ** { static **$* *; } -keepclassmembers class <2>$<3> { kotlinx.serialization.KSerializer serializer(...); } ``` With obfuscation `LoginRoute$Companion.class` renamed to `a.class`: ``` package fsd; import kotlin.Metadata; import kotlinx.a.b; @metadata(mv = {2, 2, 0}, k = 1, xi = 48, d1 = {"\000\026\n\002\030\002\n\002\020\000\n\002\b\003\n\002\030\002\n\002\030\002\n\000\b\003\030\0002\0020\001B\t\b\002\006\004\b\002\020\003J\f\020\004\032\b\022\004\022\0020\0060\005\006\007"}, d2 = {"Lfsd/LoginRoute$Companion;", "", "<init>", "()V", "serializer", "Lkotlinx/serialization/KSerializer;", "Lfsd/LoginRoute;", "composeApp"}) public final class a { private a() {} public final b serializer() { return (b)LoginRoute$$serializer.INSTANCE; } } ``` Which is covered only by the new rule in this PR: ``` -if @kotlinx.serialization.Serializable class ** -keepclassmembers class <1> { kotlinx.serialization.KSerializer serializer(...); } ``` Without it, `serializer()` is removed. ## Testing - new test - snippet from the issue ``` import androidx.compose.ui.window.singleWindowApplication import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import kotlinx.serialization.Serializable fun main() = singleWindowApplication { NavHost( navController = rememberNavController(), startDestination = LoginRoute() ) { composable<LoginRoute> {} } } @serializable data class LoginRoute(val id: Long? = null) ``` with this in `build.gradle.kts`: ``` compose.desktop { application { mainClass = "MainKt" nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "org.jetbrains.nav_cupcake" packageVersion = "1.0.0" } buildTypes.release.proguard { obfuscate.set(true) } } } ``` ## Release Notes ### Fixes - Desktop Fix `runRelease` task when navigation and `obfuscate.set(true)` are used
terrakok
approved these changes
Aug 18, 2025
Modified the reasons in description, the previous explanation wasn't correct entirely |
igordmn
added a commit
that referenced
this pull request
Aug 18, 2025
…sed (#5384) Fixes https://youtrack.jetbrains.com/issue/CMP-8050/Desktop-runRelease-crash-when-upgrade-to-CMP-1.8.0-rc01 `./gradlew runRelease` throws an error: ``` Exception in thread "main" kotlinx.a.g: Serializer for class 'LoginRoute' is not found ``` in this code: ``` import androidx.compose.ui.window.singleWindowApplication import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import kotlinx.serialization.Serializable fun main() = singleWindowApplication { NavHost( navController = rememberNavController(), startDestination = LoginRoute() ) { composable<LoginRoute> {} } } @serializable data class LoginRoute(val id: Long? = null) ``` with obfuscation enabled: ``` compose.desktop { application { mainClass = "MainKt" nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "org.jetbrains.nav_cupcake" packageVersion = "1.0.0" } buildTypes.release.proguard { obfuscate.set(true) } } } ``` It crashes because: - we use `@InternalSerializationApi kotlinx.serialization.serializer` which is used by Navigation - it uses reflection underneath. Looks like it tries to find serializer 2 ways: - Looking at the field `static final LoginRoute.Companion.serializer` - Looking at the `inner class LoginRoute.Companion` and its name - The [the default](https://github.com/Kotlin/kotlinx.serialization/blob/4667a18/rules/common.pro) rules: - [no obfuscation] work by the second way, but doesn't work by the first - [with obfuscation] don't work by both ways The new rule support the first for both obfuscated/non-obfuscated code ## Details ### Old rules #### Without obfuscation ``` // LoginRoute.class public final class LoginRoute { public static final Companion Companion = new Companion((byte)0); ... public static final class Companion { private Companion() {} } } // LoginRoute$Companion.class public final class Companion { private Companion() {} } ``` #### With obfuscation ``` // LoginRoute.class @serializable public final class LoginRoute { public static final a Companion = new a((byte)0); ... } // a.class public final class a { private a() {} } ``` ### With new rule #### Without obfuscation ``` // LoginRoute.class @serializable public final class LoginRoute { public static final Companion Companion = new Companion((byte)0); ... public static final class Companion { private Companion() {} public final KSerializer<LoginRoute> serializer() { return (KSerializer<LoginRoute>)LoginRoute.$serializer.INSTANCE; } } } // LoginRoute$Companion.class public final class Companion { private Companion() {} public final KSerializer<LoginRoute> serializer() { return (KSerializer<LoginRoute>)LoginRoute.$serializer.INSTANCE; } } ``` #### With obfuscation ``` // LoginRoute.class @serializable public final class LoginRoute { public static final a Companion = new a((byte)0); ... } // a.class public final class a { private a() {} public final b serializer() { return (b)LoginRoute$$serializer.INSTANCE; } } ``` ## Testing - new test - snippet above doesn't produce the error anymore ## Release Notes ### Fixes - Desktop Fix `runRelease` task when navigation and `obfuscate.set(true)` are used (cherry picked from commit af7c80c)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes https://youtrack.jetbrains.com/issue/CMP-8050/Desktop-runRelease-crash-when-upgrade-to-CMP-1.8.0-rc01
./gradlew runRelease
throws an error:in this code:
with obfuscation enabled:
It crashes because:
@InternalSerializationApi kotlinx.serialization.serializer
which is used by Navigationstatic final LoginRoute.Companion.serializer
inner class LoginRoute.Companion
and its nameThe new rule support the first for both obfuscated/non-obfuscated code
Details
Old rules
Without obfuscation
With obfuscation
With new rule
Without obfuscation
With obfuscation
Testing
Release Notes
Fixes - Desktop
Fix
runRelease
task when navigation andobfuscate.set(true)
are used