Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop ProGuard from stripping the Serializable interface from a class

Is there an explicit way to stop ProGuard from changing a class from implementing an interface?

I have a class that implements java.io.Serializable, let's call it com.my.package.name.Foo. I've found that after running through ProGuard, it no longer implements Serializable. I get null after I cast from Serializable to Foo and false if I check an instance with instanceof Serializable. I've made sure to set ProGuard to ignore this class:

-keep class com.my.package.name.Foo

I've also tried:

-keep class com.my.package.name.Foo { *; }

and I've also tried the whole package by doing this:

-keep class com.my.package.name.** { *; }

or:

-keep class com.my.package.** { *; }

and also just to keep all Serializable classes:

-keep class * implements java.io.Serializable { *; }

but to no avail. I have another class in a sibling package (roughly: com.my.package.name2.Bar) that also implements Serializable and is used similarly but has no issues.

I'm not sure it's relevant, but I'm packing this in a jar for use with Android. The code that uses these classes include putting them in Bundles which is why I need Serializable. I considered that perhaps somehow ProGuard thinks that Foo is never used as a Serializable but that seems unlikely given that I pass it as a parameter to Bundle.putSerializable(String, Serializable) and also I do an implicit cast: Serializable serializable = foo;. In fact, when I debug, I can see the Foo get put into the Bundle and I can examine the Bundle and see the instance of Foo there, but when retrieving it the cast fails.

like image 384
kabuko Avatar asked Apr 18 '13 01:04

kabuko


People also ask

How do you keep a class in ProGuard?

-keepclassmembernames. This is the most permissive keep directive; it lets ProGuard do almost all of its work. Unused classes are removed, the remaining classes are renamed, unused members of those classes are removed, but then the remaining members keep their original names.

What is Dontwarn in ProGuard?

If your code works fine without the missing classes, you can suppress the warnings with '-dontwarn' options. ( http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)

What is the difference between ProGuard and R8?

R8 has higher Kotlin language support as compared to proguard. Proguard is mainly used by applications developed using Java. Usually, the R8 compiler is much faster than the proguard compiler. This makes R8 more efficient.

How do you set ProGuard rules?

When you create a new project or module using Android Studio, the IDE creates a <module-dir>/proguard-rules.pro file for you to include your own rules. You can also include additional rules from other files by adding them to the proguardFiles property in your module's build.gradle file.


1 Answers

I had the same issue fixed using below config.

-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

Official Documentation http://proguard.sourceforge.net/manual/examples.html#serializable

like image 175
Sabeer Avatar answered Sep 18 '22 19:09

Sabeer