Proguard and XStream with omitField() on Android

瘦欲@ 提交于 2019-12-03 22:22:23

As I said, the problem disappears if you -dontobfuscate but let's suppose you don't want that.

The solution is to keep more attributes:

-keepattributes EnclosingMethod, InnerClasses
-keepattributes *Annotation*
-keepattributes Signature

Once you get it working you can narrow down which parts of the XStream code to keep as well. I have:

-keep class com.thoughtworks.xstream.converters.extended.SubjectConverter { *; }
-keep class com.thoughtworks.xstream.converters.extended.ThrowableConverter { *; }
-keep class com.thoughtworks.xstream.converters.extended.StackTraceElementConverter { *; }
-keep class com.thoughtworks.xstream.converters.extended.CurrencyConverter { *; }
-keep class com.thoughtworks.xstream.converters.extended.RegexPatternConverter { *; }
-keep class com.thoughtworks.xstream.converters.extended.CharsetConverter { *; }

-keep class com.thoughtworks.xstream.annotations.** { *; }

You can also disable a lot of warnings related to XStream.

For more details you can find my version controlled project files here:

I seem to be one of many to have problems with ProGuard and XStream for Android. After some trial and research, the following is what works for me - a complete config file together with some explanatory comments why I did what I did. Note that my priority was to obfuscate, but I did not care much about optimizing or shrinking.

And you need to remember that with this config (which keeps public members for libraries - see below) you will need to use "public" members for the class that is used by XStream to create your XML, because XStream will use member names for XML labels - and you do not want your XML labels to be changed to "a", "b" or "c" :) Good luck!

###########################################################
#
# FLAGS
#
###########################################################


# Not sure if I need this one, but seems to do no harm
-keepdirectories

# I needed NOT to optimize for SWT or XStream would not work, but for Android I do not seem to need to do that.
# However, if I try to shrink, XStream fails for Android. This different behaviour is a bit odd and black magic.
# However, I do not much care about optimization or size, and stability is more important for me, so let's
# neither optimize nor shrink (and shrinking saved us only about 1.5% of the size anyway).
#
# Note: this was not all that was necessary to make XStream run for Android - see other comments
# (search for XStream)
-dontshrink
-dontoptimize
# The following was configured for Android by default but now it does not make sense because I do not optmize, so disable just in case.
# -optimizationpasses 5

# Not sure if I need this one, but seems to do no harm.
-keeppackagenames

# This was configured for Android by default and it can only help.
-dontusemixedcaseclassnames

# This was configured for Android by default, and it is the default option as of ProGuard 4.5 anyway.
-dontskipnonpubliclibraryclasses

# ProGuard documentation says:
# For Java 6, preverification is optional, but as of Java 7, it is required.
# Only when eventually targeting Android, it is not necessary, so you can then
# switch it off to reduce the processing time a bit.
-dontpreverify

# Specifies to write out some more information during processing. If the
# program terminates with an exception, this option will print out the
# entire stack trace, instead of just the exception message.
-verbose

# Since I have turned off optmization, it makes no sense to have the following
# option enabled.
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# The followig was necessary or it would not build, as it otherwise wants a totally clean build first.
-ignorewarnings

###########################################################
#
# -keep SPECIFICATIONS
#
###########################################################

# I tried adding those to fix the XStream problem, but in the end fixed it differently (see other comments).
#-keepattributes EnclosingMethod, InnerClasses
#-keepattributes *Annotation*
#-keepattributes Signature

# The following was configured for Android by default.
-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.ILicensingService

# I tried adding those to fix the XStream problem, but in the end fixed it differently (see other comments).
# However, it might still be a good idea to stay away from thoughtworks for stability's sake.
# (Not sure if the second keep does not include the first one.)
-keep class com.thoughtworks.xstream.*
-keep class com.thoughtworks.xstream.* {
    public protected <methods>;
    public protected <fields>;
}

# The following plus not-shrinking seems necessary to make XStream run for Android.
# But again, as for SWT, I did not need to exclude all, public and protected methods and fields:
# just doing the public fields was enough.
#    public protected <methods>;
#    public protected <fields>;
-keep public class * {
    public <fields>;
}

# This was configured for Android by default - and very necessary it is too.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# I put it in because we might need this one in the future.
# This was default for the Windows installation of ProGuard, which said:
# Also keep - Database drivers. Keep all implementations of java.sql.Driver.
-keep class * extends java.sql.Driver

# This was configured for Android by default.
-keepclasseswithmembernames class * {
    native <methods>;
}

# This was configured for Android by default.
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

# This was configured for Android by default.
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

# This was configured for Android by default.
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# This was configured for Android by default.
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

XStream seems to introspect on the EnclosingMethod attribute, so keeping it in your ProGuard configuration may help:

-keepattributes EnclosingMethod

The ProGuard manual provides a list of attributes that you may want to keep. The error message suggests that you're already keeping the InnerClasses attribute, which is probably required indeed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!