Proguard и XStream с помощью omitField () на Android - PullRequest
1 голос
/ 21 июня 2011

Я использовал XStream для десериализации xml в своем приложении для Android, и сейчас я пытаюсь добавить Proguard (обфускатор) в смесь.

Вот исключение времени выполнения, с которым я столкнулся (полное: pastebin ):

WARN/System.err(6209): net.lp.collectionista.util.a.g: XStream could not parse the response
WARN/System.err(6209):     at net.lp.collectionista.a.s.a(Collectionista:215)
    ...
WARN/System.err(6209): Caused by: com.thoughtworks.xstream.converters.ConversionException: id : id in loader dalvik.system.PathClassLoader[/data/app/net.lp.collectionista-2.apk] : id : id in loader dalvik.system.PathClassLoader[/data/app/net.lp.collectionista-2.apk]
WARN/System.err(6209): ---- Debugging information ----
WARN/System.err(6209): message             : id : id in loader dalvik.system.PathClassLoader[/data/app/net.lp.collectionista-2.apk]
WARN/System.err(6209): cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
WARN/System.err(6209): cause-message       : id : id in loader dalvik.system.PathClassLoader[/data/app/net.lp.collectionista-2.apk]
WARN/System.err(6209): class               : net.lp.collectionista.jaxb.googlebooks.search.Feed
WARN/System.err(6209): required-type       : java.lang.Object
WARN/System.err(6209): path                : /feed/entry/id
WARN/System.err(6209): line number         : 1
WARN/System.err(6209): -------------------------------
WARN/System.err(6209):     at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(Collectionista:89)
    ...
WARN/System.err(6209):     at com.thoughtworks.xstream.XStream.fromXML(Collectionista:861)
    ...
WARN/System.err(6209): Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: id : id in loader dalvik.system.PathClassLoader[/data/app/net.lp.collectionista-2.apk]
WARN/System.err(6209):     at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(Collectionista:68)
    ...

Само собой разумеется, что это прекрасно работает без Proguard. Я использую сжатие, оптимизацию и запутывание здесь, хотя я отключил все это для любого класса XStream, а также для любого класса, который соответствует модели для полей xml:

-keep class net.lp.collectionista.jaxb.** { *; }
-keep class com.thoughtworks.xstream.** { *; }

Я могу подтвердить из запутанного jar, а также из mapping.txt (для методов), что все упомянутые классы существуют и не запутаны, так что нетронутый AFAICT. Я также храню аннотации.

Исключение для меня довольно очевидно. У меня есть:

        xstream.omitField(Feed.class, "id");

среди других. Кажется, что вызов omitField () больше не работает, и он начинает искать класс модели "id" из-за Proguard. Вот где я застрял, даже после погружения в код XStream. Весь вызов omitField в запутанном конечном результате, кажется, не поврежден, так что здесь может быть дополнительно нарушено? Он также не должен быть «Feed.class», так как он все еще там. Что мне не хватает? Что является хорошим следующим шагом для отладки?

РЕДАКТИРОВАТЬ: Я заметил, что файлы классов классов xstream в моем запутанном банке немного меньше оригинальных, даже с -dontoptimize. Что еще уронили?

EDIT2: Я начинаю думать, что это связано с отсутствием предупреждений dex, подобных следующему:

[apply] warning: Ignoring InnerClasses attribute for an anonymous inner class
[apply] (com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$1) that doesn't come with an
[apply] associated EnclosingMethod attribute. This class was probably produced by a
[apply] compiler that did not target the modern .class file format. The recommended
[apply] solution is to recompile the class from source, using an up-to-date compiler
[apply] and without specifying any "-target" type options. The consequence of ignoring
[apply] this warning is that reflective operations on this class will incorrectly
[apply] indicate that it is *not* an inner class.

... а может и нет ...

EDIT3: Наконец, несмотря на устранение многих других ошибок и проблем, таких как ошибка SimException , я смог заставить ее работать в некоторых ограниченных случаях. Таким образом, я мог бы точно указать на шаг запутывания. То есть, по крайней мере, если я добавлю «-dontobfuscate», проблема исчезнет. это не первый раз, когда я играю с этим, так что, возможно, это обходные пути для других проблем или более узкая конфигурация, которая также облегчает эту проблему. Итак, вот я снова спрашиваю: когда я уже защитил основные части xstream и мои классы моделей от обфускации с помощью «-keep», что еще может создать этот беспорядок?

Если вам нужна дополнительная информация, дайте мне знать.

Ответы [ 3 ]

3 голосов
/ 02 ноября 2011

Как я уже сказал, проблема исчезнет, ​​если вы -dontobfuscate, но давайте представим, что вы этого не хотите.

Решение состоит в том, чтобы сохранить больше атрибутов:

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

Как только вы запустите его, вы можете сузить, какие части кода XStream также следует сохранить. У меня есть:

-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.** { *; }

Вы также можете отключить множество предупреждений, связанных с XStream.

Для получения более подробной информации вы можете найти файлы моего проекта с управлением версиями здесь:

2 голосов
/ 03 июня 2013

Кажется, я один из многих, у кого проблемы с ProGuard и XStream for Android.После некоторых проб и исследований, вот что работает для меня - полный конфигурационный файл вместе с некоторыми пояснительными комментариями, почему я сделал то, что сделал.Обратите внимание, что моим приоритетом было запутывание, но я не особо заботился об оптимизации или сжатии.

И вам нужно помнить, что с этим конфигом (который содержит открытые члены для библиотек - см. Ниже) вам нужно будет использовать«публичные» члены для класса, который используется XStream для создания вашего XML, потому что XStream будет использовать имена членов для меток XML - и вы не хотите, чтобы ваши метки XML были изменены на «a», «b» или «c»:) Удачи!

###########################################################
#
# 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 *;
}
0 голосов
/ 23 июня 2011

XStream, кажется, анализирует атрибут EnclosingMethod, поэтому сохранение его в конфигурации ProGuard может помочь:

-keepattributes EnclosingMethod

В руководстве ProGuard содержится список атрибутов, которые вы можете сохранить. Сообщение об ошибке предполагает, что вы уже сохраняете атрибут InnerClasses, который, вероятно, действительно требуется.

...