From ffd64a2e70a9eaf9da06e3af2438209db3e140d6 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 15 May 2026 21:03:28 +0000 Subject: [PATCH] fix(desktop): add project ProGuard rules to unblock release packaging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compose Multiplatform 1.11.0 tightened its default ProGuard ruleset so `proguardReleaseJars` now fails on unresolved references that 1.10.3 tolerated silently. The v1.09.0 release tag-build hit this on every desktop leg (macOS DMG, Windows MSI, Linux DEB/RPM, Linux AppImage), which is why only Android APKs and the macOS-arm64 / Linux Amy CLI bundles made it onto the GitHub release. Three groups of references were flagged: - Jackson kotlin-module 2.21.x value-class converters (`IntValueClassBoxConverter`, `ValueClassKeyDeserializer$*`, …) invoke `MethodHandle.invokeExact` with polymorphic signatures ProGuard cannot resolve against the abstract MethodHandle. - okhttp's optional TLS adapters (`okhttp3.internal.graal.*`, `BouncyCastle/Conscrypt/OpenJSSEPlatform`) reference classes from runtime backends that aren't on the desktop classpath; okhttp falls back to the JDK default in their absence. - JNA's `com.sun.jna.internal.Cleaner` inner classes touch synthetic `access$N` accessors that ProGuard's class-member analysis cannot follow. Add `desktopApp/compose-rules.pro` with `-dontwarn` rules for each bucket and wire it through `compose.desktop.application.buildTypes .release.proguard.configurationFiles`. Verified locally by re-running `:desktopApp:proguardReleaseJars` (now BUILD SUCCESSFUL) and `:desktopApp:packageReleaseDeb` (gets past ProGuard; only fails on the sandbox missing `fakeroot`, which CI installs in the existing "Install RPM tooling" step). --- desktopApp/build.gradle.kts | 9 ++++++++ desktopApp/compose-rules.pro | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 desktopApp/compose-rules.pro diff --git a/desktopApp/build.gradle.kts b/desktopApp/build.gradle.kts index 786f5a0fc..9f98f3ee9 100644 --- a/desktopApp/build.gradle.kts +++ b/desktopApp/build.gradle.kts @@ -129,6 +129,15 @@ compose.desktop { rpmPackageVersion = appVersion.replace("-", "~") } } + + // Compose Multiplatform 1.11.0 tightened the default ProGuard rules so + // unresolved references in transitive deps (Jackson kotlin-module value + // classes, okhttp's optional TLS adapters, JNA cleaner internals) now + // fail `proguardReleaseJars`. Project-level rules below add the missing + // `-dontwarn` directives. + buildTypes.release.proguard { + configurationFiles.from(project.file("compose-rules.pro")) + } } } diff --git a/desktopApp/compose-rules.pro b/desktopApp/compose-rules.pro new file mode 100644 index 000000000..a840209b3 --- /dev/null +++ b/desktopApp/compose-rules.pro @@ -0,0 +1,40 @@ +# ProGuard rules consumed by Compose Multiplatform's `proguardReleaseJars` +# task (see `compose.desktop.application.buildTypes.release.proguard` wiring +# in build.gradle.kts). +# +# Compose Multiplatform 1.11.0 ships a stricter default ruleset than 1.10.x +# and now treats unresolved references as fatal. The warnings below come from +# third-party libraries that have always carried optional code paths; they +# were silently tolerated on 1.10.3 and broke desktop packaging on 1.11.0. + +# --- Jackson kotlin-module 2.21.x value-class converters --------------------- +# Generated converters call `MethodHandle.invokeExact(...)` with polymorphic +# signatures that ProGuard cannot resolve against the abstract MethodHandle +# declaration. They are only used reflectively by Jackson when (de)serializing +# Kotlin `value class` types — safe to suppress. +-dontwarn com.fasterxml.jackson.module.kotlin.** + +# --- okhttp optional runtime platforms -------------------------------------- +# okhttp ships TLS adapters for GraalVM native-image, Conscrypt, BouncyCastle, +# OpenJSSE, and Jetty boot. None of these are on the desktop classpath; okhttp +# falls back to the JDK default. Suppress the warnings without keeping the +# unused classes. +-dontwarn okhttp3.internal.graal.** +-dontwarn okhttp3.internal.platform.BouncyCastlePlatform +-dontwarn okhttp3.internal.platform.BouncyCastlePlatform$* +-dontwarn okhttp3.internal.platform.ConscryptPlatform +-dontwarn okhttp3.internal.platform.ConscryptPlatform$* +-dontwarn okhttp3.internal.platform.OpenJSSEPlatform +-dontwarn okhttp3.internal.platform.OpenJSSEPlatform$* +-dontwarn org.conscrypt.** +-dontwarn org.bouncycastle.** +-dontwarn org.openjsse.** +-dontwarn org.graalvm.** +-dontwarn com.oracle.svm.** + +# --- JNA internal cleaner --------------------------------------------------- +# `com.sun.jna.internal.Cleaner$CleanerThread` references package-private +# synthetic accessors (`access$100` …) that ProGuard's class member analysis +# cannot follow through nested inner classes. The accessors exist at runtime. +-dontwarn com.sun.jna.internal.Cleaner +-dontwarn com.sun.jna.internal.Cleaner$*