Files
amethyst/desktopApp
m 931a217251 fix(desktop): mirror Android ProGuard strategy for release builds
Compose Multiplatform 1.11.0 wired ProGuard 7.7.0 into the release
build for the first time. With optimize + shrink + obfuscate all on,
the desktop v1.09.1 DMG hit four distinct runtime failures:

  A. Jackson's SerializationFeature.values()/valueOf() stripped, so
     Class.getEnumConstants() returned null and ObjectMapper failed
     to initialise (app didn't launch). Fixed in #2921.
  B. fr.acinq.secp256k1.* JNI bridge classes renamed by obfuscate;
     bundled libsecp256k1-jni.dylib could not FindClass the original
     names, so KeyPair / sign / verify crashed on first use.
  C. androidx.sqlite-bundled native declarations (nativeThreadSafeMode,
     nativeOpen) shrunk away because no Kotlin caller referenced them
     directly; libsqliteJni.dylib raised NoSuchMethodError on the first
     EventStore query.
  D. ProGuard's method/specialization/returntype optimize sub-pass
     generated a synthetic okio bridge (Okio__OkioKt.buffer$<hash>)
     whose declared return type was RealBufferedSource but whose body
     returned the BufferedSource super-interface. The JVM verifier
     rejected the bridge, killing every OkHttp connection.

The Android (mobile) module solved the same class of problems in
amethyst/proguard-rules.pro with a single global strategy:

    -dontobfuscate
    -keepnames class ** { *; }
    -keep enum ** { *; }
    + per-library -keep rules for JNA / libsodium / libscrypt
    + first-party -keep com.vitorpamplona.**

This commit replays that strategy in desktopApp/compose-rules.pro
and drops the previous optimize.set(false)/obfuscate.set(false)
escape hatch in desktopApp/build.gradle.kts. Shrink and optimize
both stay on; only the one optimize sub-pass that produced invalid
okio bytecode (method/specialization/returntype) is disabled.

Additional desktop-only keep rules (Jackson, full JNA, VLCj,
SLF4J, OkHttp / Conscrypt / BouncyCastle / OpenJSSE / Graal
dontwarns) stay in place. Two libraries shipped only on desktop
also get explicit -keep rules so their native callbacks survive
shrink:

  - androidx.sqlite.** + native <methods>; (nativeThreadSafeMode
    was previously stripped even with -keepnames, because shrink
    removes members the global rule doesn't cover).
  - pt.davidafsilva.apple.** + native <methods>; for the macOS
    Keychain JNI bridge.

Verified on macOS arm64 packageReleaseDmg:
  - javap on the post-ProGuard jars confirms:
      * fr.acinq.secp256k1.NativeSecp256k1 keeps its FQCN.
      * SerializationFeature.values() / valueOf() present.
      * androidx.sqlite.driver.bundled.BundledSQLiteDriverKt
        retains native nativeThreadSafeMode() + nativeOpen().
      * Okio__OkioKt only exposes buffer(Source): BufferedSource
        and buffer(Sink): BufferedSink — no specialized
        buffer$<hash> bridge.
  - Bundled app launches and reaches VLC MediaPlayerFactory init
    with zero VerifyError / NoSuchMethodError / UnsatisfiedLinkError
    in the log.
2026-05-16 11:38:15 +10:00
..