Proguard的混淆是打破了SimpleXML打破了、Proguard、SimpleXML

2023-09-05 07:47:57 作者:你要是调戏我,我就非礼你

我使用的SimpleXML在我的Andr​​oid项目,一切工作正常,直到我混淆code。然后,错误开始浇筑

在XML的部分如下:

 <类别成功=真正的>
  &所述;类别ID =102标题=Magazin的父=0num_mags =114>
    <类别ID =15标题=孔斯特父=102num_mags =13>
      <类别ID =17标题=设计父=15num_mags =10>< /类>
      <类别ID =18标题=高级+时装父=15num_mags =2>
...
 

我有两个类:CategoryItemList:

  @root(名称=类别)
公共类CategoryItemList {

    私人最终名单,其中,CategoryItem> mCategoryItems;
    / **
     *创建一个新的类别的项目清单。
     *
     *参数categoryItems类的项目列表
     * /
    公共CategoryItemList(@ElementList(名称=类别,内嵌= TRUE)最终名单,其中,CategoryItem> categoryItems){
        mCategoryItems = categoryItems;
    }
    @ElementList(名称=类别,内嵌= TRUE)
    公开名单< CategoryItem> getCategoryItems(){
        返回mCategoryItems;
    }
}
 

和CategoryItem:

  @root(名称=类别)
公共类CategoryItem {
    私人最终诠释MID;
    私人最终字符串mCaption;
    私人最终诠释mParent;
    私人最终诠释mNumberOfMagazines;
    私人最终的ArrayList< CategoryItem> mSubCategoryItems;
    / **
     *创建一个新的类别的项目。
     *
     *参数ID类别ID
     *参数标题类别的名称
     *参数父父类
     * @参数numMags杂志的数量从该类别
     * /
    公共CategoryItem(@Attribute(NAME =ID)最终诠释ID,
                        @Attribute(名称=说明),最后弦乐标题,
                        @Attribute(NAME =父)最终诠释父母,
                        @Attribute(NAME =num_mags)最终诠释numMags,
                        @ElementList(名称=类别,内嵌= TRUE,所需= FALSE)最后的ArrayList< CategoryItem> subCategoryItems){
        MID = ID;
        mCaption =标题;
        mParent =父母;
        mNumberOfMagazines = numMags;
        mSubCategoryItems = subCategoryItems;
    }

    @Attribute(NAME =ID)
    公众诠释的getId(){
        返回MID;
    }

    @Attribute(名称=说明)
    公共字符串getCaption(){
        字符串categoryName = NULL;

        尝试 {
            类别名= URLDe coder.de code(mCaption,UTF-8);
        }赶上(最终UnsupportedEncodingException E){
            e.printStackTrace();
        }
        返回类别名;
    }

    @Attribute(NAME =父)
    公众诠释getParentId(){
        返回mParent;
    }

    @Attribute(NAME =num_mags)
    公众诠释getNumbersOfMagazines(){
        返回mNumberOfMagazines;
    }

    @ElementList(名称=类别,内嵌= TRUE,所需= FALSE)
    公众的ArrayList< CategoryItem> getSubCategory(){
        返回mSubCategoryItems;
    }
}
 
Proguard混淆器详细介绍以及使用方法

现在,当我混淆code,如果我离开了-keepattributes的注释的我得到的PersistenceException:构造不匹配类。

如果我有它,我得到一个无法确定通用类型构造函数参数1异常,所有这些在运行时。 正如你所看到的,名字在那里,我试图-keep全班抱着他们,都没有用。

如何配置Proguard的与simplexml的?工作

编辑:我proguard.cfg文件如下:(这有点塞满了所有我试过的事情,但是这是当前版本)

  -dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dont preverify
-verbose
-printseeds
-dontoptimize
-keepattributes *注释*
-keepattributes EnclosingMethod

-libraryjars< java.home> /lib/rt.jar(使用javax / XML /物流/ **)

-keep公共类*扩展android.app.Activity
-keep公共类*扩展android.app.Application
-keep公共类*扩展android.app.Service
-keep公共类*扩展android.content.BroadcastReceiver
-keep公共类*扩展android.content.ContentProvider
-keep公共类*扩展android.app.backup.BackupAgentHelper
-keep公共类*扩展的Andr​​oid。preference。preference

-keepclasseswithmembers类* {
    天然的LT;方法&gt ;;
}

-keepclasseswithmembers类* {
    公共和LT; INIT>(android.content.Context,android.util.AttributeSet);
}

-keepclasseswithmembers类* {
    公共和LT; INIT>(android.content.Context,android.util.AttributeSet,INT);
}

-keepclassmembers枚举* {
    公共静态** []值();
    公共静态**的valueOf(java.lang.String中);
}

-keep类*实现android.os.Parcelable {
  公共静态最终android.os.Parcelable $造物主*;
}

-dontwarn android.support **,de.greenrobot **,org.simpleframework.xml。**
-keep类com.crittercism ** {*。 }
-keepclassmembernames类com.crittercism ** {*。 }
-keepclasseswithmembers类com.crittercism ** {*。 }

-keep类org.simpleframework ** {*。 }
-keepclassmembernames类org.simpleframework ** {*。 }
-keepclasseswithmembers类org.simpleframework ** {*。 }

-keep类crittercism.android。**
-keepclassmembers公共类com.crittercism * {*;}

-keep公共类数据库。** {
    公共静态<领域取代;
}

-keep类android.support。**
-keepclasseswithmembers类android.support **。{*;}

-keep类org.simpleframeork。**
-keepclasseswithmembers类org.simpleframeork **。{*;}

-keep类的javax。**
-keepclasseswithmembers类的javax **。{*;}

-keep类com.test.category。**
-keepclassmembernames类com.test.category ** {*。 }
。-keepclasseswithmembers类com.test.category ** {*;}

-keep类com.test.download。**
-keepclassmembernames类com.test.download ** {*。 }
-keepclasseswithmembers类com.test.download **。{*;}

-keep类org.simpleframework ** {*。 }
-keep类org.simpleframework.xml ** {*。 }
-keep类org.simpleframework.xml.core ** {*。 }
-keep类org.simpleframework.xml.util ** {*。 }
-keep类org.simpleframework.xml.stream ** {*。 }

-keepclassmembers类*实现了java.io.Serializable {
    私有静态最后java.io.ObjectStreamField [] serialPersistentFields;
    私人无效的writeObject(java.io.ObjectOutputStream中);
    私人无效的readObject(java.io.ObjectInputStream中);
    java.lang.Object中writeReplace();
    java.lang.Object中的readResolve();
}
 

解决方案

您已经想通了,保持注释是一个好主意。你也可以尝试的类型参数添加到@ElementList注释 - 显然有一个与泛型类型擦除和SimpleXML的问题需要更多的提示有关的元素类型列表中的

您也可以玩弄-keepattributes签名,*注释*:

  

签名属性是必需的,以便能够访问通用   在JDK 5.0编译和更高时类型。

I am using simplexml in my android project, and everything works fine until I obfuscate the code. Then, errors start pouring in.

Part of the XML is as follows:

<categories success="true">
  <category id="102" caption="Magazin" parent="0" num_mags="114" >
    <category id="15" caption="Kunst" parent="102" num_mags="13" >
      <category id="17" caption="Design" parent="15" num_mags="10" ></category>
      <category id="18" caption="Haute+Couture" parent="15" num_mags="2" >
...

I have two classes: CategoryItemList:

@Root(name = "categories")
public class CategoryItemList {

    private final List<CategoryItem> mCategoryItems;
    /**
     * Create a new category items list.
     * 
     * @param categoryItems the list of category items
     */
    public CategoryItemList(@ElementList(name = "category", inline = true) final List<CategoryItem> categoryItems) {
        mCategoryItems = categoryItems;
    }
    @ElementList(name = "category", inline = true)
    public List<CategoryItem> getCategoryItems() {
        return mCategoryItems;
    }
}

and CategoryItem:

@Root(name = "category")
public class CategoryItem {
    private final int mId;
    private final String mCaption;
    private final int mParent;
    private final int mNumberOfMagazines;
    private final ArrayList<CategoryItem> mSubCategoryItems;
    /**
     * Creating a new category item.
     * 
     * @param id the category id
     * @param caption the name of category
     * @param parent the parent category
     * @param numMags the number of magazines from that category
     */
    public CategoryItem(@Attribute(name = "id") final int id,
                        @Attribute(name = "caption") final String caption,
                        @Attribute(name = "parent") final int parent,
                        @Attribute(name = "num_mags") final int numMags,
                        @ElementList(name = "category", inline = true, required = false) final ArrayList<CategoryItem> subCategoryItems) {
        mId = id;
        mCaption = caption;
        mParent = parent;
        mNumberOfMagazines = numMags;
        mSubCategoryItems = subCategoryItems;
    }

    @Attribute(name = "id")
    public int getId() {
        return mId;
    }

    @Attribute(name = "caption")
    public String getCaption() {
        String categoryName = null;

        try {
            categoryName = URLDecoder.decode(mCaption, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return categoryName;
    }

    @Attribute(name = "parent")
    public int getParentId() {
        return mParent;
    }

    @Attribute(name = "num_mags")
    public int getNumbersOfMagazines() {
        return mNumberOfMagazines;
    }

    @ElementList(name = "category", inline = true, required = false)
    public ArrayList<CategoryItem> getSubCategory() {
        return mSubCategoryItems;
    }
}

Now, when I obfuscate the code, if I leave out "-keepattributes Annotation" I get a PersistenceException: Constructor not matched for class.

If I include it, I get an "Unable to determine generic type for parameter 1 of constructor" exception, all these at runtime. As you can see, the names are there, and I tried to -keep the entire class holding them, all to no avail.

How can I configure Proguard to work with simplexml?

EDIT: My proguard.cfg file is as follows: (it's a bit stuffed with all the things I've tried, but this is the current version)

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-printseeds
-dontoptimize
-keepattributes *Annotation*
-keepattributes EnclosingMethod

-libraryjars <java.home>/lib/rt.jar (javax/xml/stream/** )

-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

-keepclasseswithmembers class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-dontwarn android.support.**,de.greenrobot.**,org.simpleframework.xml.**
-keep class com.crittercism.**{ *; }
-keepclassmembernames class com.crittercism.**{ *; }
-keepclasseswithmembers class com.crittercism.**{ *; }

-keep class org.simpleframework.**{ *; }
-keepclassmembernames class org.simpleframework.**{ *; }
-keepclasseswithmembers class org.simpleframework.**{ *; }

-keep class crittercism.android.**
-keepclassmembers public class com.crittercism.*{ *;}

-keep public class database.** {
    public static <fields>;
}

-keep class android.support.**
-keepclasseswithmembers class android.support.** { *;}

-keep class org.simpleframeork.**
-keepclasseswithmembers class org.simpleframeork.** { *;}

-keep class javax.**
-keepclasseswithmembers class javax.** { *;}

-keep class com.test.category.**
-keepclassmembernames class com.test.category.** { *; }
-keepclasseswithmembers class com.test.category.** { *;}

-keep class com.test.download.**
-keepclassmembernames class com.test.download.** { *; } 
-keepclasseswithmembers class com.test.download.** { *;}

-keep class org.simpleframework.**{ *; } 
-keep class org.simpleframework.xml.**{ *; } 
-keep class org.simpleframework.xml.core.**{ *; } 
-keep class org.simpleframework.xml.util.**{ *; }
-keep class org.simpleframework.xml.stream.**{ *; }

-keepclassmembers class * implements java.io.Serializable {
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

解决方案

You already figured out that keeping annotation is a good idea. You may also try to add type parameter to @ElementList annotation - apparently there is a problem with generic type erasure and simplexml needs additional hint about type of elements in the list

you may also play around with -keepattributes Signature, *Annotation*:

The "Signature" attribute is required to be able to access generic types when compiling in JDK 5.0 and higher.