Unable to use proguard

Hi. I am trying to compile my app using proguard, and I am getting an error with the backendless classes. I have added the proguard exceptions as suggested here https://backendless.com/documentation/users/android/users_requirements.htm, but it is not working. I am using backendless from gradle (compile ‘com.backendless:android:3.0.3’)
Please find attached my proguard-rules and error log.

backendless.txt (82.81kB)

Try to modify the instruction in proguard config file to:

-dontwarn com.backendless.**
-dontwarn weborb.**
-keep class weborb.** {*;}

Mark

Thanks Mark. It is working now. I think the android documentation needs to be updated.

Ok, cool. We’ll make the changes in the docs.

Hi again. I found another problem while using proguard. I have this code:

BackendlessDataQuery dataQueryOptions = new BackendlessDataQuery();
dataQueryOptions.setPageSize(100);


Backendless.Persistence.of(MemeTemplate.class).find(dataQueryOptions, new AsyncCallback<BackendlessCollection<MemeTemplate>>() {
    @Override
    public void handleResponse(BackendlessCollection<MemeTemplate> response) {
        if (response != null && response.getCurrentPage() != null) {
            mTemplates = response.getCurrentPage();
        }
        mAdapter.notifyDataSetChanged(mTemplates);
    }


    @Override
    public void handleFault(BackendlessFault fault) {
        Utils.getInstance(CatalogActivity.this).showErrorMessage(fault);
    }
});

If I don’t use proguard, it works as expected, getting some results in BackendlessResponse object. But when I enable proguard, it doesn’t get anything, it returns a BackendlesResponse but getCurrentPage returns zero results instead of what I am expecting (about 20). I thought it could be because proguard is ofbuscating the classes names or the constants I am using for backendless keys, but I have checked with some log traces and the decompiled apk that it isn’t, both seems to be ok. This is where I initialize Backendless:



public class MyApplication extends Application {


    public MyApplication() {
        super();
    }


    @Override
    public void onCreate() {
        super.onCreate();


        Backendless.initApp(this,
                BuildConfig.BACKENDLESS_APP_ID,
                BuildConfig.BACKENDLESS_SECRET_KEY,
                BuildConfig.BACKENDLESS_VERSION);


        // Map classes to Backendless tables
        Backendless.Persistence.mapTableToClass(MemeTemplate.class.getSimpleName(), MemeTemplate.class);
    }
}

Don’t know if I’m missing something …

Try adding the following directives in the proguard config:

-keep public class backendless.** {
public protected ;
}-keep public class YOURPACKAGE.
* {
public protected *;
}
where “YOURPACKAGE” is the package name where the MemeTemplate class is placed.

Regards,
Mark

Hi Mark. Merry Christmas :slight_smile:

I already had -keep public for my class. I have added it for backendless.**, but it is still not working. This is what I have in proguard for backendless:

-dontwarn com.backendless.**
-dontwarn weborb.**
-keep class weborb.** {*;}


-keep public class backendless.** {
    public protected *;
}


-keep public class com.tactel.memegenerator.model.** {
    public protected *;
}

Thanks.

Merry Christmas to you too, Andrés!

Does the MemeTemplate class have the default no-arg constructor? If not, could you explicitly add it to the class and try again?

Regards,
Mark

Yes, it has the default no-arg constructor. This is my code:

public class MemeTemplate {


    private String objectId;
    private Date created;
    private Date updated;


    private String name;
    private String description;
    private String imageUrl;


    public MemeTemplate() {


    }


    public String getObjectId() {
        return objectId;
    }


    public void setObjectId(String objectId) {
        this.objectId = objectId;
    }


    public Date getCreated() {
        return created;
    }


    public void setCreated(Date created) {
        this.created = created;
    }


    public Date getUpdated() {
        return updated;
    }


    public void setUpdated(Date updated) {
        this.updated = updated;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public String getDescription() {
        return description;
    }


    public void setDescription(String description) {
        this.description = description;
    }


    public String getImageUrl() {
        return imageUrl;
    }


    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
}

That makes me think it is a bug in Proguard… Why would it change the behavior of a perfectly working program?

Does Backendless has a sample app that uses proguard? I could use it to verify if I am missing something else.

This is my gradle config for the release build:

release {
    minifyEnabled true
    shrinkResources true
    signingConfig signingConfigs.release
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    buildConfigField 'String', 'BACKENDLESS_APP_ID', '"XXXXXX"'
    buildConfigField 'String', 'BACKENDLESS_SECRET_KEY', '"XXXXXXXX"'
    buildConfigField 'String', 'BACKENDLESS_VERSION', '"v1"'
}

I just noticed that I gave you wrong package name for Backendless. It should be this (add com. before backendless.**):

-keep public class com.backendless.** {
public protected *;
}

Almost … Now I’m getting something more strange than before: a BackendlessCollection of 10 objects (expected 20 and in my code I have pageSize = 100) but all of them are empty: all properties return null.

Hi Mark.

Do you have a sample backendless android app that uses proguard?

Thanks

Hi Andrés,

No, we do not have a sample app that uses proguard. I just tried an example similar to yours and was able to get the results both in release and debug compilations with the following settings:

-dontwarn com.backendless.**
-dontwarn weborb.**


-keep class weborb.** {*;}
-keep class com.backendless.** { *; }
-keep class com.tactel.memegenerator.model.**.** { *; }

Please try it and let me know if it works for you.

Regards,
Mark

Hi Mark.

Now I am getting the message: “Unable to retrieve data - Unknow entity”

Could you please zip up the project (or a sample demonstrating the problem) and email it to me?

Sure. I just sent it.

Hi Andrés,
Please accept our apologies for taking so long to figure out and thanks for helping us find out the drawbacks in the docs.

Try the following rules:

# Backendless
-dontwarn com.backendless.**
-dontwarn weborb.**

-keep class weborb.** {*;}
-keep class com.backendless.** {*;}
-keep class com.tactel.memegenerator.model.** {*;}
# Backendless

Note that the last line has only single .** instead of double.
These rules should work fine, as they will keep Backendless’ and you models’ classes totally untouched.

Nice app, by the way, I liked it :slight_smile:
Keep it up!

Regards,
Sergey