Pertanyaan Proguard - PersistenceException: Constructor tidak cocok untuk kelas


saya menggunakan retrofit2.0 di aplikasi saya dengan simpleframework.xml Perpustakaan.

Masalahnya adalah ketika saya menjalankan aplikasi tanpa proguard itu berfungsi dengan baik namun ketika saya menjalankan proguard saya mendapatkan Kesalahan dalam log berikut.

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

Kelas A memiliki konstruktor no / default yang seharusnya berfungsi. Masih saya tambahkan a No Argument Constructor. Tapi itu tidak memperbaiki masalah ini.

Kelas SEBUAH

@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
}

Seperti yang Anda lihat tidak ada konstruktor (Menambahkan konstruktor kosong bawaan membuat masalah). Jadi standarnya No Argument Constructor harus bekerja dengan baik. Namun saya mencoba dengan konstruktor berikut dan ini menghilangkan kesalahan.

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;
}

Tetapi saya memiliki terlalu banyak file untuk diubah jika saya ingin melakukannya dengan cara ini. Selain konstruktor yang membutuhkan semua nilai yang dipetakan seharusnya tidak diperlukan. Saya memiliki beberapa kelas yang meng-host lebih dari 50 anggota variabel (saya menyederhanakan kelas contoh untuk memasukkan hanya dua variabel anggota). Kelas ini berisi sekitar 30 dan kode sudah terlalu lama untuk diposting di sini.

Masalahnya adalah saya memiliki banyak kelas yang bekerja pada asumsi konstruktor No Argument untuk setiap kelas.

Cukup menambahkan konstruktor untuk semua tidak layak.

Saya proguard-rules.pro (hanya dengan aturan obfuscation lib yang relevan).

#-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>(...);
}

Mungkin perlu dicatat bahwa sebelum Kesalahan ini saya dapatkan

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

Dipecahkan bahwa dengan menambahkan argumen 'nama' di @Element Anotasi. Jadi salah satu alasan saya enggan untuk mengubah semua file adalah bagaimana jika Error lain merayap naik.

EDIT 1: Jadi setelah 2 hari mencari solusi, saya menyerah dan akhirnya menambahkan konstruktor ke semua kelas. Masalahnya adalah perpustakaan memanggil konstruktor hanya untuk yang tersedia xml-tags. Katakanlah untuk kelas A diatas jika saja Kode negara tersedia di xml

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

Maka saya membutuhkan konstruktor dengan hanya satu argumen country_code untuk membuatnya bekerja

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

Yang membuat solusi yang ditemukan tidak dapat digunakan.

EDIT 2: Menemukan solusi! Menjaga kelas POJO dalam aturan proguard memperbaiki kesalahan ini. Tetapi saya lebih suka tidak menyimpan kelas-kelas ini.

Jadi saya menjaga pertanyaan ini terbuka setidaknya untuk saat ini atau sampai seseorang dapat memberi tahu saya mengapa saya harus menyimpan file-file ini.


6
2017-11-21 07:33


asal


Jawaban:


Saya kira bahwa masalah Anda adalah bahwa Anda tidak menyimpan atribut dan itu jelas tergantung pada atribut yang Anda gunakan. Dalam kasus saya, ini adalah bagaimana saya mengatasinya, beri tahu saya jika itu berhasil untuk Anda:

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

1
2018-06-28 13:16



coba tambahkan baris di bawah ini dalam file proguard Anda. Itu harus menyelesaikan masalah Anda

-dontnote retrofit2.Platform
-keepattributes Signature
-keepattributes Exceptions

dan hapus garis di bawah ini

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

0
2017-07-04 10:05