10

With one of my app, I had a problem with one of my Serialized classes when I try to update my APK.

Indeed, there were problems related to objects saved with the previous version of the apk and the new version of the apk.

In the latest APK (in production on Android Market), I've forgot to configure my proguard.cfg for Serializable class (and so their static final long serialVersionUID member)...

So when I try in my new APK to reload this previous stored Serializable class, I've a InvalidClassException problem in the StackTrace DDMS :

04-24 18:17:40.120: W/System.err(1204): java.io.InvalidClassException: cu; Incompatible class (SUID): cu: static final long serialVersionUID =6593847879518920343L; but expected cu: static final long serialVersionUID =0L;
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.verifyAndInit(ObjectInputStream.java:2380)
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1662)
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:683)
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1803)
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2003)
04-24 18:17:40.125: W/System.err(1204):     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1960)

I know it was a obfuscation problem with Serializable objects and their serialVersionUID...

After reading Proguard and Serialized Java Objects here which is clearly expose my problem, I'm not able to solve my problem...

In my next APK I've add this in my proguard.cfg :

-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 ;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

to avoid the problem for next updates, my I really need to get back these old objects...

I've try to change the serialVersionUID with 6593847879518920343L or 0L, no success...

Any idea ?

Thanks in advance for your answers !

StephaneT
  • 479
  • 5
  • 11

1 Answers1

5

You could try this:

  1. Compute the serialVersionUIDs of the obfuscated serializable classes and add them to the current source code.
  2. Obfuscate the new code, preserving the serialVersionUIDs, but also making sure the serializable classes are mapped to the earlier obfuscated names (with the option -applymapping).
Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
  • 9
    How to compute the serialVersionUIDs of the obfuscated serializable classes? – peceps May 07 '15 at 14:57
  • 2
    This answer is missing example code on how to achieve the solutions – McFarlane Jun 09 '16 at 08:28
  • 1
    @peceps You can compute the serialVersionUIDs of serialized classes by writing a custom `ObjectInputStream` that prints the values during de-serialization. See e.g. [this answer](https://stackoverflow.com/a/1322186/2660705). – V.S. Jun 13 '19 at 13:04