Foso / Ktorfit

HTTP client generator / KSP plugin for Kotlin Multiplatform (Android, iOS, Js, Jvm, Native, WasmJs)) using KSP and Ktor clients inspired by Retrofit https://foso.github.io/Ktorfit
https://foso.github.io/Ktorfit
Apache License 2.0
1.62k stars 43 forks source link

[Bug]: proguard crash in typeOf reflect #339

Closed vickyleu closed 1 year ago

vickyleu commented 1 year ago

Ktorfit version

1.4.1

What happened and how can we reproduce this issue?

W/System.err: java.lang.IllegalArgumentException: Class declares 0 type parameters, but 1 were provided.
W/System.err:     at kotlin.reflect.full.KClassifiers.createType(SourceFile:53)
W/System.err:     at kotlin.reflect.jvm.internal.CachesKt.getOrCreateKTypeWithTypeArguments(SourceFile:69)
W/System.err:     at kotlin.reflect.jvm.internal.CachesKt.getOrCreateKType(SourceFile:58)
W/System.err:     at kotlin.reflect.jvm.internal.ReflectionFactoryImpl.typeOf(SourceFile:123)
W/System.err:     at kotlin.jvm.internal.Reflection.typeOf(SourceFile:133)
W/System.err:     at com.slotary.furniture.request._BaseApiImpl.furnitureTypeList(SourceFile:77)
W/System.err:     at com.slotary.furniture.repository.impl.ApiRepositoryImpl.furnitureTypeList(Unknown Source:2)
W/System.err:     at com.slotary.furniture.repository.presenter.KmmApiPresenter.furnitureTypeList(Unknown Source:2)
W/System.err:     at com.slotary.furniture.request.BaseApi$DefaultImpls.furnitureTypeList$default(SourceFile:36)
W/System.err:     at com.slotary.furniture.viewModel.HomeViewModel$loadData$2.invokeSuspend(SourceFile:36)
W/System.err:     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(SourceFile:33)
W/System.err:     at kotlinx.coroutines.DispatchedTaskKt.resume(SourceFile:256)
W/System.err:     at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(SourceFile:190)
W/System.err:     at kotlinx.coroutines.DispatchedTaskKt.dispatch(SourceFile:161)
W/System.err:     at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(SourceFile:397)
W/System.err:     at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(SourceFile:431)
W/System.err:     at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(SourceFile:420)
W/System.err:     at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(SourceFile:518)
W/System.err:     at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(SourceFile:500)
W/System.err:     at kotlinx.coroutines.EventLoopImplBase.processNextEvent(SourceFile:284)
W/System.err:     at kotlinx.coroutines.DefaultExecutor.run(SourceFile:108)

2023-06-08 22:57:06.675 16905-16905/com.slotary.furniture W/System.err:     at java.lang.Thread.run(Thread.java:1012)

What did you expect to happen?

crash in


val _requestData = RequestData(ktorfitRequestBuilder = _ext,
        returnTypeName =
            "kotlinx.coroutines.flow.Flow<com.slotary.furniture.base.api.ApiResponse<com.slotary.furniture.request.model.FurnitureTypeListResponse>>",
        returnTypeInfo = typeInfo<Flow<ApiResponse<FurnitureTypeListResponse>>>()) <<<<

Is there anything else we need to know about?

isMinifyEnabled = true //false //
            signingConfig = signingConfigs.getByName("release")
            isShrinkResources = true
            // Includes the default ProGuard rules files that are packaged with
            // the Android Gradle plugin. To learn more, go to the section about
            // R8 configuration files.
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguards/proguard-rules.pro"
            )
            optimization{
                keepRules {
                    ignoreExternalDependencies(
                        "de.jensklingenberg.ktorfit:ktorfit-lib-light",
                        "org.jetbrains.kotlinx:kotlinx-serialization-json",
                        "io.ktor:ktor-client-encoding",
                        "io.ktor:ktor-client-core",
                    )
                }
            }

proguard-rules.pro

# By default, the flags in this file are appended to flags specified
# in /usr/share/android-studio/data/sdk/tools/proguard/proguard-android.txt

# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

##---------------Begin: proguard configuration common for all Android apps ----------
-optimizationpasses 5
-dontusemixedcaseclassnames
#-dontskipnonpubliclibraryclasses
#-dontskipnonpubliclibraryclassmembers
#-dontpreverify
-verbose

-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!method/removal/*

-allowaccessmodification
-keepattributes *Annotation*

# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile
-keepattributes Signature

-keep class kotlin.reflect.** { *; }
-keepclassmembers class kotlin.reflect.** { *; }
# When I remove this, java.security.cert.CertificateException: X.509 not found is thrown
-keep class org.bouncycastle.** { *; }
-keep interface org.bouncycastle.**

# I got the missing classes from missing_rules.txt and added the package names that created the problem here:
-keep class org.conscrypt.** { *; }
-keep class io.netty.** { *; }

-dontwarn java.lang.Module.**
-dontwarn java.lang.module.**
-dontwarn jakarta.servlet.**
-dontwarn ch.qos.logback.core.util.**

-dontnote androidx.**

-keepnames class * extends androidx.startup.** { *; }
# These Proguard rules ensures that ComponentInitializers are are neither shrunk nor obfuscated,
# and are a part of the primary dex file. This is because they are discovered and instantiated
# during application startup.
-keep class * extends androidx.startup.**  {
    # Keep the public no-argument constructor while allowing other methods to be optimized.
    <init>();
}

##serialization
-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

# Don't print notes about potential mistakes or omissions in the configuration for kotlinx-serialization classes
# See also https://github.com/Kotlin/kotlinx.serialization/issues/1900
-dontnote kotlinx.serialization.**

# Serialization core uses `java.lang.ClassValue` for caching inside these specified classes.
# If there is no `java.lang.ClassValue` (for example, in Android), then R8/ProGuard will print a warning.
# However, since in this case they will not be used, we can disable these warnings
-dontwarn kotlinx.serialization.internal.ClassValueReferences

# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn java.lang.Module.**
-dontwarn java.lang.module.**
-dontwarn jakarta.servlet.**
-dontwarn ch.qos.logback.core.util.**
-dontwarn org.jetbrains.kotlin.serialization.**

-keep public class * extends com.slotary.furniture.base.api.ApiResponse { *; }

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.**
-dontnote com.android.vending.licensing.**
-keepclassmembers class androidx.vectordrawable.graphics.drawable.**

-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
-keep interface okhttp3.** { *; }
# 保留 Ktor 相关类和方法
-keep class io.ktor.** { *; }
-keepclassmembers class io.ktor.** { *; }

# 保留 Ktor 所需的注解
-keepattributes *Annotation*
-keepclassmembers class * {
    @io.ktor.** <methods>;
}

-keep public class androidx.compose.runtime.**

-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);
    boolean isTraceInProgress();
    void traceEventStart( int, int, int, java.lang.String);
    void traceEventEnd();
}

-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepclassmembers class kotlinx.coroutines.** {
    volatile <fields>;
}
-keepclassmembers class kotlin.coroutines.SafeContinuation {
    volatile <fields>;
}

# https://github.com/Kotlin/kotlinx.coroutines/issues/2046
-dontwarn android.annotation.SuppressLint

# https://github.com/JetBrains/compose-jb/issues/2393
-dontnote kotlin.coroutines.jvm.internal.**
-dontnote kotlin.internal.**
-dontnote kotlin.jvm.internal.**
-dontnote kotlin.reflect.**
-dontnote kotlinx.coroutines.debug.internal.**
-dontnote kotlinx.coroutines.internal.**
-keep class kotlin.coroutines.Continuation
-keep class kotlinx.coroutines.CancellableContinuation
-keep class kotlinx.coroutines.channels.Channel
-keep class kotlinx.coroutines.CoroutineDispatcher
-keep class kotlinx.coroutines.CoroutineScope
# this is a weird one, but breaks build on some combinations of OS and JDK (reproduced on Windows 10 + Corretto 16)
-dontwarn org.graalvm.compiler.core.aarch64.AArch64NodeMatchRules_MatchStatementSet*

# Ktor
-keep class io.ktor.** { *; }
#-keep class kotlinx.coroutines.** { *; }
-dontwarn kotlinx.atomicfu.**
-dontwarn io.netty.**
-dontwarn com.typesafe.**
-dontwarn org.slf4j.**
-dontwarn javax.**
-dontwarn org.codehaus.**
-dontwarn sun.reflect.**

-dontwarn com.oracle.svm.**
-dontwarn java.lang.management.**

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# Preserve all native method names and the names of their classes.
-keepclasseswithmembers class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
  public static <fields>;
}

# Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#-keep public class * {
#    public protected *;
#}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------

#---------------Begin: proguard configuration for support library  ----------
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
-dontwarn com.google.ads.**
##---------------End: proguard configuration for Gson  ----------

##---------------Begin: proguard configuration for Gson  ----------

# Gson specific classes
-keep class sun.misc.** { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.example.model.** { *; }

##---------------End: proguard configuration for Gson  ----------

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
vickyleu commented 1 year ago
# 保留Kotlin协程相关的类和方法
-keep class kotlinx.coroutines.** { *; }
# 保留Kotlin反射相关的类和方法
-keep class io.ktor.util.reflect.** { *; }
-keep class kotlin.reflect.** { *; }
-keepclassmembers class io.ktor.util.reflect.** { *; }
-keepclassmembers class kotlin.reflect.** { *; }

# 如果使用了Ktor客户端,保留相关的类和方法
-keep class io.ktor.client.** { *; }

keep ktor reflect solved the crash