I am using retrofit2.0
in my app with simpleframework.xml
library.
The problem is when I run the app without proguard it works fine however when I run proguard I get the following Error in logs.
E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.PersistenceException: Constructor not matched for class A
The class A has no/default constructor which should work. Still I added a No Argument Constructor. But that didn't rectify the issue.
Class 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
}
As you can see there is no constructor (Adding the default empty constructor keeps the issue). So default No Argument Constructor should work just as well. However I tried with the following constructor and this removes the error.
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;
}
But I have too many files to change if I want to do it this way. Besides a constructor requiring all the values mapped shouldn't be required. I have quite a few classes which host more than 50 member variables (I simplified the example class to include only two member variables). This class contains about 30 and code would've been simply too long to post here.
The thing is I have loads of classes working on the assumption of No Argument constructor for each class.
Simply adding constructors for all is not feasible.
My proguard-rules.pro (with only relevant lib obfuscation rules).
#-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>(...);
}
It might be worth noting that before this Error I was getting
E/ERROR: java.lang.RuntimeException: org.simpleframework.xml.core.ElementException: Element 'version' does not have a match in class A at line 1
Solved that by adding 'name' argument in @Element
Annotation. So one of the reasons I'm reluctant to change all the files is what if another Error creeps up.
EDIT 1: So after 2 days of searching for a solution I gave up and finally added constructors to all the classes. The thing is the library calls constructor for only the available xml-tags. Say for the above class A if only country_code was available in the xml
<xml>
<data>
<country_code>PK</country_code>
</data>
</xml>
Then I'd need a constructor with only one argument of country_code to make it work
public A(@Element(name = "country_code") String country_code) {
this.country_code = country_code;
}
Which makes the found solution unusable.
EDIT 2: Found a workaround! Keeping the POJO classes in the proguard rules fixes this error. But I would rather not keep these classes.
And so I'm keeping this question open at-least for now or until someone can tell me why I should keep these files.