Proguard - PersistenceException:构造函数与类不匹配

Posted

技术标签:

【中文标题】Proguard - PersistenceException:构造函数与类不匹配【英文标题】:Proguard - PersistenceException: Constructor not matched for class 【发布时间】:2018-05-04 14:11:42 【问题描述】:

我在我的应用程序中使用retrofit2.0simpleframework.xml 库。

问题是当我在没有 proguard 的情况下运行应用程序时,它可以正常工作,但是当我运行 proguard 时,我在日志中收到以下错误。

E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.PersistenceException: Constructor not matched for class A

A 类没有应该工作的/默认构造函数。我仍然添加了一个 No Argument Constructor。但这并没有解决问题。

A类

@Root(name = "data",strict = false)
public class A 
    @Element(name = "baseurl",required = false)
    private String baseURl;
    @Element(name = "country_code")
    private String country_code;

    //  Setters and getters

如您所见,没有构造函数(添加默认的空构造函数会保留问题)。所以默认的 No Argument Constructor 应该也能正常工作。但是我尝试使用以下构造函数,这消除了错误。

public A(@ELement(name = "baseurl") String baseUrl,
         @Element(name = "country_code") String country_code)     // Add all the elements from the xml in the constructor i.e. if a new element is added a new constructor would have to be written.
    baseURl = baseUrl;
    this.country_code = country_code;

但是如果我想这样做,我有太多文件要更改。除了需要所有映射的值的构造函数之外,不应该是必需的。我有很多类包含 50 多个成员变量(我将示例类简化为仅包含两个成员变量)。这个类包含大约 30 个,代码太长了,不能在这里发布。

问题是我有很多类在假设每个类都没有参数构造函数。

简单地为所有人添加构造函数是不可行的。

我的 proguard-rules.pro(只有相关的 lib 混淆规则)。

#-keepattributes *Annotation*

-dontwarn retrofit2.**
-keep class retrofit2.**  *; 

-dontwarn com.bea.xml.stream.**
-dontwarn org.simpleframework.xml.stream.**
-keep class org.simpleframework.xml.** *; 
-keepclassmembers,allowobfuscation class * 
    @org.simpleframework.xml.* <fields>;
    @org.simpleframework.xml.* <init>(...);

可能值得注意的是,在此错误之前我得到了

E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'version' does not have a match in class A at line 1

通过在 @Element 注释中添加“名称”参数解决了这个问题。因此,我不愿意更改所有文件的原因之一是如果出现另一个错误怎么办。

编辑 1: 因此,在寻找解决方案 2 天后,我放弃了,最后为所有类添加了构造函数。问题是库只为可用的 xml-tags 调用构造函数。如果在 xml 中只有 country_code 可用,则说上述 A 类

<xml>
    <data>
        <country_code>PK</country_code>
    </data>
</xml>

然后我需要一个只有一个 country_code 参数的构造函数才能使其工作

public A(@Element(name = "country_code") String country_code) 
    this.country_code = country_code;

这使得找到的解决方案无法使用。

编辑 2: 找到了解决方法!将 POJO 类保留在 proguard 规则中可修复此错误。但我宁愿不保留这些课程。

因此,我至少暂时或直到有人能告诉我为什么要保留这些文件为止。

【问题讨论】:

我也遇到同样的问题,无法解决 你能分享你的整个xml吗?我可以检查一下。 如果您的应用程序在没有 proguard 和发布版本的情况下工作,您也可以更新 只要未启用 proguard,应用程序就可以正常工作。顺便说一句,我找到了一个我不喜欢的解决方案:保留所有 POJO 对象(在 proguard 中)。我真的不喜欢!我仍然愿意在不保留所有这些类的情况下解决这个问题。 @rajlaxmi_jagdale 查看更新。 【参考方案1】:

我猜你的问题是你没有保留任何属性,这显然取决于你使用的属性。就我而言,这就是我处理它的方式,让我知道它是否适合您:

## https://square.github.io/retrofit/ ##
-dontwarn retrofit2.**
-keep class retrofit2.**  *; 
-keepattributes Signature
-keepattributes Exceptions
 -keepclasseswithmembers class * 
    @retrofit2.http.* <methods>;


## Simple XML ##
-dontwarn org.simpleframework.xml.stream.**
-keep public class org.simpleframework.**  *; 
-keep class org.simpleframework.xml.**  *; 
-keep class org.simpleframework.xml.core.**  *; 
-keep class org.simpleframework.xml.util.**  *; 

-keepattributes ElementList, Root, *Annotation*

-keepclassmembers class * 
    @org.simpleframework.xml.* *;

【讨论】:

不起作用,日志中仍然出现相同的异常。顺便说一句,没有必要继续改造2。 你是否也保留了 Exceptions 属性?【参考方案2】:

尝试在您的 proguard 文件中添加以下这些行。它应该可以解决您的问题

-dontnote retrofit2.Platform
-keepattributes Signature
-keepattributes Exceptions

并删除以下这些行

-dontwarn retrofit2.**
-keep class retrofit2.**  *; 

【讨论】:

@abbas 你能检查一下吗?

以上是关于Proguard - PersistenceException:构造函数与类不匹配的主要内容,如果未能解决你的问题,请参考以下文章

使用属性打开/关闭 Proguard

proguard.ParseException:proguard.cfg 中的未知选项“-encryptstrings”

ProGuard惯用法

Proguard Maven 插件不使用指定的 Proguard 版本

Proguard 查询,正在使用哪一个

Proguard 返回错误 1 ​​- 项目 bin 文件夹中没有 proguard.txt 文件?