How to stop ProGuard from removing Serializable interface from 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 found that after starting ProGuard it no longer implements Serializable . I get null after I cast from Serializable to Foo and false if I test an instance with instanceof Serializable . I made sure that ProGuard ignores this class:

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

I also tried:

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

and I also tried the whole package by doing the following:

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

or

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

and also just save all the classes Serializable :

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

but to no avail. I have another class in the sibling package (approximately: com.my.package.name2.Bar ) that also implements Serializable and is used in a similar way, but has no problems.

I'm not sure if this is relevant, but I collect it in a bank for use with Android. The code that uses these classes includes their placement in the Bundle , so I need Serializable . I thought that maybe somehow ProGuard thinks that Foo never used as Serializable , but it seems unlikely given that I pass it as a parameter to Bundle.putSerializable(String, Serializable) , and also I do an implicit listing : Serializable serializable = foo; . In fact, when I debug, I can see that Foo get put in the Bundle , and I can check the Bundle and see the instance of Foo there, but it gets reset when it is received.

+7
source share
2 answers

ProGuard never separates interfaces defined in libraries (e.g. Serializable) from classes of processed code (e.g. Foo). Library code can be passed to these interfaces, so they cannot be deleted.

I get null after I migrated from Serializable to Foo

This means that for starters, the instance must be null. Your analysis will be correct if you get a ClassCastException. You can check that Foo still implements Serializable with javap . The problem probably lies elsewhere. For tips on serialization, you can see the ProGuard manual> Examples> Handling Serializable Classes .

Update:

In this case, it turns out to be a configuration problem. ProGuard can only process class files if it knows everything about their hierarchy (like a compiler). You really need to specify runtime classes:

 -libraryjars <java.home>/lib/rt.jar 

or for Android:

 -libraryjars /usr/local/android-sdk/platforms/android-17/android.jar 

Android Ant / Eclipse builds automatically list all the necessary -injars / -outjars / -libraryjars options, but you must specify them yourself during the custom build process. CFR. ProGuard Guide> Examples> Complete Android App .

Note that the -dontwarn option causes warnings to go away, but not problems. Use it if it is really necessary.

+4
source

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

+21
source

All Articles