Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing Proguard/R8 rules with moshi-sealed-codegen #556

Closed
mhelder opened this issue Feb 28, 2024 · 1 comment 路 Fixed by #603
Closed

Missing Proguard/R8 rules with moshi-sealed-codegen #556

mhelder opened this issue Feb 28, 2024 · 1 comment 路 Fixed by #603

Comments

@mhelder
Copy link

mhelder commented Feb 28, 2024

moshi-sealed-codegen does not seem to work as advertised with minification enabled.

Reproducer: https://github.com/mhelder/moshix-sealed-missing-proguard-rules
// edit: forgot to push my branch 馃う - fixed now!

It takes the Message sample from the Moshi-sealed docs and does this:

val json = """{ "type": "success", "value": "Yay" }"""
val moshi = Moshi.Builder().build()
val adapter = moshi.adapter(Message::class.java)
val message = adapter.fromJson(json)

Works fine with isMinifyEnabled = false. It'll output Success(value=Yay) on screen.

Now flip the isMinifyEnabled flag for the debug build type or run the release.

R8 full mode on (default):

FATAL EXCEPTION: main
Process: com.example.app, PID: 19895
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: java.lang.IllegalArgumentException: Cannot serialize abstract class com.example.app.data.model.Message
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4164)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:230)
	at android.os.Looper.loop(Looper.java:319)
	at android.app.ActivityThread.main(ActivityThread.java:8893)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.IllegalArgumentException: Cannot serialize abstract class com.example.app.data.model.Message
	at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:93)
	at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
	at com.squareup.moshi.Moshi.adapter(Moshi.java:106)
	at com.squareup.moshi.Moshi.adapter(Moshi.java:80)
	at com.example.app.MainActivity.onCreate(MainActivity.kt:16)
	at android.app.Activity.performCreate(Activity.java:8944)
	at android.app.Activity.performCreate(Activity.java:8913)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)聽
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)聽
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)聽
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)聽
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)聽
	at android.os.Handler.dispatchMessage(Handler.java:106)聽
	at android.os.Looper.loopOnce(Looper.java:230)聽
	at android.os.Looper.loop(Looper.java:319)聽
	at android.app.ActivityThread.main(ActivityThread.java:8893)聽
	at java.lang.reflect.Method.invoke(Native Method)聽
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)聽
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)聽

R8 full mode off (set android.enableR8.fullMode=false in gradle.properties):

FATAL EXCEPTION: main
Process: com.example.app, PID: 20057
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.MainActivity}: java.lang.RuntimeException: Failed to find the generated JsonAdapter class for class com.example.app.data.model.Message
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4164)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.RuntimeException: Failed to find the generated JsonAdapter class for class com.example.app.data.model.Message
    at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:590)
    at com.squareup.moshi.StandardJsonAdapters$1.create(StandardJsonAdapters.java:61)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:146)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:106)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:80)
    at com.example.app.MainActivity.onCreate(MainActivity.kt:16)
    at android.app.Activity.performCreate(Activity.java:8944)
    at android.app.Activity.performCreate(Activity.java:8913)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)聽
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)聽
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)聽
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)聽
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)聽
    at android.os.Handler.dispatchMessage(Handler.java:106)聽
    at android.os.Looper.loopOnce(Looper.java:230)聽
    at android.os.Looper.loop(Looper.java:319)聽
    at android.app.ActivityThread.main(ActivityThread.java:8893)聽
    at java.lang.reflect.Method.invoke(Native Method)聽
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)聽
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)聽
Caused by: java.lang.ClassNotFoundException: com.example.app.data.model.MessageJsonAdapter
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:536)
    at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:564)
    at com.squareup.moshi.StandardJsonAdapters$1.create(StandardJsonAdapters.java:61)聽
    at com.squareup.moshi.Moshi.adapter(Moshi.java:146)聽
    at com.squareup.moshi.Moshi.adapter(Moshi.java:106)聽
    at com.squareup.moshi.Moshi.adapter(Moshi.java:80)聽
    at com.example.app.MainActivity.onCreate(MainActivity.kt:16)聽
    at android.app.Activity.performCreate(Activity.java:8944)聽
    at android.app.Activity.performCreate(Activity.java:8913)聽
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)聽
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)聽
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)聽
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)聽
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)聽
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)聽
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)聽
    at android.os.Handler.dispatchMessage(Handler.java:106)聽
    at android.os.Looper.loopOnce(Looper.java:230)聽
    at android.os.Looper.loop(Looper.java:319)聽
    at android.app.ActivityThread.main(ActivityThread.java:8893)聽
    at java.lang.reflect.Method.invoke(Native Method)聽
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)聽
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)聽
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.app.data.model.MessageJsonAdapter" on path: DexPathList[[dex file "/data/data/com.example.app/code_cache/.overlay/base.apk/classes.dex", zip file "/data/app/~~wmAybjC_Rs2XrETNE2mbJg==/com.example.app-3vp2orfM7M1VnaqJ66cISw==/base.apk"],nativeLibraryDirectories=[/data/app/~~wmAybjC_Rs2XrETNE2mbJg==/com.example.app-3vp2orfM7M1VnaqJ66cISw==/lib/arm64, /system/lib64, /system/system_ext/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at java.lang.Class.classForName(Native Method)聽
    at java.lang.Class.forName(Class.java:536)聽
    at com.squareup.moshi.internal.Util.generatedAdapter(Util.java:564)聽
    at com.squareup.moshi.StandardJsonAdapters$1.create(StandardJsonAdapters.java:61)聽
    at com.squareup.moshi.Moshi.adapter(Moshi.java:146)聽
    at com.squareup.moshi.Moshi.adapter(Moshi.java:106)聽
    at com.squareup.moshi.Moshi.adapter(Moshi.java:80)聽
    at com.example.app.MainActivity.onCreate(MainActivity.kt:16)聽
    at android.app.Activity.performCreate(Activity.java:8944)聽
    at android.app.Activity.performCreate(Activity.java:8913)聽
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)聽
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)聽
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)聽
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)聽
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)聽
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)聽
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)聽
    at android.os.Handler.dispatchMessage(Handler.java:106)聽
    at android.os.Looper.loopOnce(Looper.java:230)聽
    at android.os.Looper.loop(Looper.java:319)聽
    at android.app.ActivityThread.main(ActivityThread.java:8893)聽
    at java.lang.reflect.Method.invoke(Native Method)聽
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)聽
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)聽

Project has no Proguard/R8 rules defined.

Rules generated under resources/META-INF/proguard:

  • moshi-com.example.app.data.model.Message.Success.pro:
-if class com.example.app.data.model.Message$Success
-keepnames class com.example.app.data.model.Message$Success
-if class com.example.app.data.model.Message$Success
-keep class com.example.app.data.model.Message_SuccessJsonAdapter {
    public <init>(com.squareup.moshi.Moshi);
}
  • moshi-com.example.app.data.model.Message.pro:
<empty file>
@MBratkowski
Copy link

I would like also bump this issue. In our production project we are facing the same problem - for debug build we don't have any problem, app is crashing for release build where isMinifyEnabled is set on true value.

I checked @mhelder sample project, and from our side we have the same configuration of class/project:

  • used generateAdapter with true value for sealed class;
  • ksp outputs contains all pro guard rules (also with the same empty file for sealed class);
  • all adapters are generated in build folder for release version;

Maybe are we missed something?

ZacSweers added a commit that referenced this issue May 28, 2024
* Fix proguard rule gen not capturing non-sealed subtypes.

Resolves #556

* Update other tests

* Don't write empty files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants