JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.12k stars 1.18k forks source link

java.lang.SecurityException: SHA-256 digest error for org/bouncycastle/operator/OperatorCreationException.class #4786

Closed LazyIonEs closed 4 months ago

LazyIonEs commented 5 months ago

Describe the bug I turned on obfuscation in the project, and when I used stringResource(Res.string.app_name), there was a crash. I'm not sure what's causing it, but when I turn off obfuscation, everything works fine again, but for some reason, I still prefer to turn on obfuscation. I don't know if it's because my obfuscation is not configured correctly. I can't solve it. Please help me with this problem

Affected platforms

Versions

To Reproduce Steps to reproduce the behavior:

  1. Run this code snippet:
    @OptIn(ExperimentalResourceApi::class)
    @Composable
    fun BugReproduction() {
       Text(stringResource(Res.string.app_name))
    }
  2. Click on 'runReleaseDistributable'
  3. See error

Expected behavior A clear and concise description of what you expected to happen. normal operation

Screenshots image

Additional context

Exception in thread "main" java.lang.SecurityException: SHA-256 digest error for org/bouncycastle/operator/OperatorCreationException.class
    at java.base/sun.security.util.ManifestEntryVerifier.verify(Unknown Source)
    at java.base/java.util.jar.JarVerifier.processEntry(Unknown Source)
    at java.base/java.util.jar.JarVerifier.update(Unknown Source)
    at java.base/java.util.jar.JarVerifier$VerifierStream.read(Unknown Source)
    at java.base/jdk.internal.loader.Resource.getBytes(Unknown Source)
    at java.base/jdk.internal.loader.URLClassPath$JarLoader$2.getBytes(Unknown Source)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(Unknown Source)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Unknown Source)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Unknown Source)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
    at org.jetbrains.compose.resources.StringResourcesKt.parseStringXml(StringResources.kt:54)
    at org.jetbrains.compose.resources.StringResourcesKt.access$parseStringXml(StringResources.kt:1)
    at org.jetbrains.compose.resources.StringResourcesKt$getParsedStrings$2$deferred$1$1$1.invokeSuspend(StringResources.kt:46)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:95)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:69)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:48)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at org.jetbrains.compose.resources.ResourceState_blockingKt.rememberResourceState(ResourceState.blocking.kt:15)
    at org.jetbrains.compose.resources.StringResourcesKt.stringResource(StringResources.kt:81)
    at ComposableSingletons$AppKt$lambda-1$1.invoke(App.kt:2083)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.material3.ProvideContentColorTextStyleKt.ProvideContentColorTextStyle-3J-VO9M(ProvideContentColorTextStyle.kt:39)
    at androidx.compose.material3.NavigationRailKt$NavigationRailItem$styledLabel$1$1.invoke(NavigationRail.kt:2189)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.material3.NavigationRailKt.NavigationRailItemLayout(NavigationRail.kt:515)
    at androidx.compose.material3.NavigationRailKt.NavigationRailItem(NavigationRail.kt:262)
    at AppKt$MainContentScreen$1$1$1.invoke(App.kt:2082)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:116)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.material3.NavigationRailKt$NavigationRail$1.invoke(NavigationRail.kt:2132)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:2134)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:112)
    at androidx.compose.material3.NavigationRailKt.NavigationRail-qi6gXK8(NavigationRail.kt:113)
    at AppKt.MainContentScreen(App.kt:75)
    at AppKt$App$1$1.invoke(App.kt:2054)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:2134)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:112)
    at AppKt$App$1.invoke(App.kt:2053)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:248)
    at androidx.compose.material3.TextKt.ProvideTextStyle(Text.kt:352)
    at androidx.compose.material3.MaterialThemeKt$MaterialTheme$1.invoke(MaterialTheme.kt:2072)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.material3.MaterialThemeKt.MaterialTheme(MaterialTheme.kt:64)
    at theme.ThemeKt.AppTheme(Theme.kt:98)
    at AppKt.App(App.kt:52)
    at MainKt$Window$2.invoke(main.kt:2049)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:116)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.ui.awt.ComposeWindow$setContent$5.invoke(ComposeWindow.desktop.kt:2156)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.ui.awt.WindowContentLayout_desktopKt.WindowContentLayout(WindowContentLayout.desktop.kt:103)
    at androidx.compose.ui.awt.ComposeWindowPanel$setContent$3$1.invoke(ComposeWindowPanel.desktop.kt:2179)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:248)
    at androidx.compose.ui.awt.ComposeWindowPanel$setContent$3.invoke(ComposeWindowPanel.desktop.kt:2176)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.ui.scene.ComposeContainer$setContent$1$1.invoke(ComposeContainer.desktop.kt:1231)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:248)
    at androidx.compose.ui.scene.ComposeContainer_desktopKt.access$ProvideContainerCompositionLocals(ComposeContainer.desktop.kt:1335)
    at androidx.compose.ui.scene.ComposeContainer$setContent$1.invoke(ComposeContainer.desktop.kt:1230)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:248)
    at androidx.compose.ui.scene.BaseComposeScene$setContent$1$2.invoke(BaseComposeScene.skiko.kt:2139)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals$75cadfc6(CompositionLocals.kt:186)
    at androidx.compose.ui.platform.Wrapper_skikoKt$setContent$2$1.invoke(Wrapper.skiko.kt:2049)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider$2acd5dcf(CompositionLocal.kt:266)
    at androidx.compose.ui.platform.Wrapper_skikoKt.access$provide$2acd5dcf(Wrapper.skiko.kt:2062)
    at androidx.compose.ui.platform.Wrapper_skikoKt$setContent$2.invoke(Wrapper.skiko.kt:2048)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jb.kt:33)
    at androidx.compose.animation.CrossfadeKt.invokeComposable(Crossfade.kt:6033)
    at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3303)
    at androidx.compose.runtime.ComposerImpl.composeContent$runtime(Composer.kt:3236)
    at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:725)
    at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1071)
    at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
    at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
    at androidx.compose.ui.platform.Wrapper_skikoKt.setContent(Wrapper.skiko.kt:47)
    at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.createComposition(MultiLayerComposeScene.skiko.kt:203)
    at androidx.compose.ui.scene.BaseComposeScene.setContent(BaseComposeScene.skiko.kt:138)
    at androidx.compose.ui.scene.ComposeSceneMediator$setContent$1.invoke(ComposeSceneMediator.desktop.kt:1458)
    at androidx.compose.ui.scene.ComposeSceneMediator.onComponentAttached(ComposeSceneMediator.desktop.kt:410)
    at androidx.compose.ui.scene.ComposeContainer.addNotify(ComposeContainer.desktop.kt:186)
    at androidx.compose.ui.awt.ComposeWindowPanel.addNotify(ComposeWindowPanel.desktop.kt:156)
    at java.desktop/java.awt.Container.addNotify(Unknown Source)
    at java.desktop/javax.swing.JComponent.addNotify(Unknown Source)
    at java.desktop/java.awt.Container.addNotify(Unknown Source)
    at java.desktop/javax.swing.JComponent.addNotify(Unknown Source)
    at java.desktop/java.awt.Container.addNotify(Unknown Source)
    at java.desktop/javax.swing.JComponent.addNotify(Unknown Source)
    at java.desktop/javax.swing.JRootPane.addNotify(Unknown Source)
    at java.desktop/java.awt.Container.addNotify(Unknown Source)
    at java.desktop/java.awt.Window.addNotify(Unknown Source)
    at java.desktop/java.awt.Frame.addNotify(Unknown Source)
    at java.desktop/java.awt.Window.pack(Unknown Source)
    at androidx.compose.ui.util.Windows_desktopKt.setSizeSafely-hQcJfNw(Windows.desktop.kt:1116)
    at androidx.compose.ui.window.Window_desktopKt$Window$5.invoke(Window.desktop.kt:1239)
    at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:1426)
    at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:1078)
    at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:1059)
    at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2304)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:504)
    at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:260)
    at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke$performUpdate(UpdateEffect.desktop.kt:55)
    at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:1064)
    at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:82)
    at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1295)
    at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:984)
    at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1005)
    at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1099)
    at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:633)
    at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:619)
    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:104)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Unknown Source)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Failed to launch JVM

compose-desktop.pro

-keepclasseswithmembers public class MainKt {
    public static void main(java.lang.String[]);
}

-keep class * implements kotlinx.coroutines.internal.MainDispatcherFactory
-keep class kotlinx.coroutines.internal.MainDispatcherFactory { *; }
-keep class kotlinx.coroutines.swing.SwingDispatcherFactory { *; }

-keep class org.tool.kit.** { *; }

-dontwarn kotlinx.coroutines.debug.*

-keep class org.bouncycastle.** { *; }
-keep class kotlin.** { *; }
-keep class kotlinx.** { *; }
-keep class kotlinx.coroutines.** { *; }
-keep class org.jetbrains.skia.** { *; }
-keep class org.jetbrains.skiko.** { *; }
-keep class com.android.apksig.** { *; }
-keep class org.sqlite.** { *; }

-assumenosideeffects public class androidx.compose.runtime.ComposerKt {
    void sourceInformation(androidx.compose.runtime.Composer,java.lang.String);
    void sourceInformationMarkerStart(androidx.compose.runtime.Composer,int,java.lang.String);
    void sourceInformationMarkerEnd(androidx.compose.runtime.Composer);
}

# Keep `Companion` object fields of serializable classes.
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
    static <1>$Companion Companion;
}

# Keep `serializer()` on companion objects (both default and named) of serializable classes.
-if @kotlinx.serialization.Serializable class ** {
    static **$* *;
}
-keepclassmembers class <2>$<3> {
    kotlinx.serialization.KSerializer serializer(...);
}

# Keep `INSTANCE.serializer()` of serializable objects.
-if @kotlinx.serialization.Serializable class ** {
    public static ** INSTANCE;
}
-keepclassmembers class <1> {
    public static <1> INSTANCE;
    kotlinx.serialization.KSerializer serializer(...);
}

# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault

-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
-dontnote kotlinx.serialization.SerializationKt

# When kotlinx.serialization.json.JsonObjectSerializer occurs

-keepclassmembers class kotlinx.serialization.json.** {
    *** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
    kotlinx.serialization.KSerializer serializer(...);
}

# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
-dontwarn org.objectweb.**
-dontwarn javax.servlet.**
-dontwarn org.xml.**
-dontwarn org.w3c.**
-dontwarn java.xml.**
-dontwarn javax.xml.**
-dontwarn java.lang.**
-dontwarn com.ibm.**
-dontwarn kotlinx.serialization.**
-dontwarn com.google.**
-dontwarn org.tukaani.**
-dontwarn org.brotli.**
-dontwarn com.github.**
-dontwarn org.apache.**
-dontwarn javax.activation.**
-dontnote javax.activation.**

-dontwarn kotlinx.datetime.**
-dontnote kotlinx.datetime.**

-dontwarn org.apache.batik.**
-dontwarn jdk.xml.**
-dontwarn org.w3c.dom.**

-dontwarn org.apache.tika.**
-dontwarn org.slf4j.**
-dontnote org.slf4j.**
-keep class org.slf4j.** { *; }
-keep class com.sun.jna.** { *; }
-keep class * implements com.sun.jna.* { *; }

# A resource is loaded with a relative path so the package of this class must be preserved.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz

# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*

# OkHttp platform used only on JVM and when Conscrypt and other security providers are available.
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
#################################### SLF4J #####################################
-dontwarn org.slf4j.**

# Prevent runtime crashes from use of class.java.getName()
-dontwarn javax.naming.**

# Ignore warnings and Don't obfuscate for now
-dontobfuscate
-ignorewarnings

-keep class org.ocpsoft.prettytime.i18n**
LazyIonEs commented 5 months ago

While I was solving the problem on my own I found this : #1675 I tried Execute packageUberJarForCurrentOS, Run with java -jar file.jar, and an error occurred. According to the operation in the article, I added

tasks.register<Zip>("repackageUberJar") {
    val packageReleaseUberJarForCurrentOS = tasks.getByName("packageReleaseUberJarForCurrentOS")
    dependsOn(packageReleaseUberJarForCurrentOS)
    val file = packageReleaseUberJarForCurrentOS.outputs.files.first()
    val output = File(file.parentFile, "${file.nameWithoutExtension}-repacked.jar")
    archiveFileName.set(output.absolutePath)
    destinationDirectory.set(file.parentFile.absoluteFile)
    exclude("META-INF/*.SF")
    exclude("META-INF/*.RSA")
    exclude("META-INF/*.DSA")
    from(project.zipTree(file))
    doLast {
        delete(file)
        output.renameTo(file)
        logger.lifecycle("The repackaged jar is written to ${archiveFile.get().asFile.canonicalPath}")
    }
}

I Execute packageUberJarForCurrentOS again, and Run with java -jar file.jar, all functions run normally, but when I want to Execute packageReleaseDistributionForCurrentOS, I found that there will still be SecurityException, so How to exclude few META-INF files for packageReleaseDistributionForCurrentOS, I think this may work for me very useful

LazyIonEs commented 5 months ago

I tried again to solve this problem myself

  1. Try to execute runReleaseDistributable and an error occurs. image
  2. Looking at the log, I found that this jar package was copied from .gradle and filtered. I don’t know what was done in the middle. image
  3. Find the original jar file, execute jarsigner -verify, and it will prompt that the jar has been verified.
  4. Find the copied jar file and execute jarsigner -verify again, prompt
    jarsigner: java.lang.SecurityException: SHA-256 digest error for org/bouncycastle/LICENSE.class
  5. Delete the internal META-INF/*.RSA, META-INF/*.SF, META-INF/*.DSA, META-INF/*.EC files from the copied bcpkix, bcprov, and bcutil jars.
  6. Execute zip -d file.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*.DSA' 'META-INF/*.EC'
  7. Double-click to launch file.app
  8. The program runs normally, no errors are reported

I want to know what was filtered in step 2, and how can I delete some files under META-INF when copying?

LazyIonEs commented 5 months ago

I'm very sorry. During my subsequent debugging, I found that this has nothing to do with resources. I will provide a minimal reproduction program to help troubleshoot the problem.

https://github.com/LazyIonEs/compose-multiplatform-desktop-template

In the above program, when I add in compose-desktop.pro

-keepclasseswithmembers public class MainKt {
     public static void main(java.lang.String[]);
}

-keep class org.bouncycastle.** { *; }

When executing runReleaseDistributable, an error message java.lang.SecurityException: SHA-256 digest error for org/bouncycastle/operator/OperatorCreationException.class will appear.

I think it may be because of the rule -keep class org.bouncycastle.** { *; }, but when I delete it, the rule in compose-desktop.pro is

-keepclasseswithmembers public class MainKt {
     public static void main(java.lang.String[]);
}

# -keep class org.bouncycastle.** { *; }

I executed runReleaseDistributable again, and an error message cannot create signer: no such algorithm: SHA256WITHRSA for provider BC appeared.

I don't understand why

Can you help me solve this problem?

LazyIonEs commented 4 months ago

The following code in the AbstractProguardTask file

        jarsConfigurationFile.ioFile.bufferedWriter().use { writer ->
            val toSingleOutputJar = joinOutputJars.orNull == true
            for ((input, output) in inputToOutputJars.entries) {
                writer.writeLn("-injars '${input.normalizedPath()}'")
                if (!toSingleOutputJar)
                    writer.writeLn("-outjars '${output.normalizedPath()}'")
            }
            if (toSingleOutputJar)
                writer.writeLn("-outjars '${mainJarInDestinationDir.ioFile.normalizedPath()}'")

            for (jmod in jmods) {
                writer.writeLn("-libraryjars '${jmod.normalizedPath()}'(!**.jar;!module-info.class)")
            }
        }

Does adding (!META-INF/*.SF,!META-INF/*.RSA,!META-INF/*.DSA) after -injars solve this problem?

 writer.writeLn("-outjars '${output.normalizedPath()}' (!META-INF/*.SF,!META-INF/*.RSA,!META-INF/*.DSA)")

All of the above is caused by the introduction of signed jar I'm not sure if this is correct, but I'm still trying to figure it out.

LazyIonEs commented 4 months ago

Solution Found

yaroslavkulinich commented 4 months ago

@LazyIonEs What the solution?

LazyIonEs commented 4 months ago

@LazyIonEs What the solution?

I exclude the package introduced in the dependency by exclude(group = "org.bouncycastle", module = "bcpkix-jdk18on"), and introduce implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) I delete the signature file in the jar package in advance by executing the command zip -d file.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*.DSA' 'META-INF/*.EC' I don't know if there are other solutions, but this method works for me

okushnikov commented 3 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.