Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue when running Proguard with the SDK (missing documentation) #96

Open
saveman71 opened this issue May 9, 2016 · 1 comment
Open

Comments

@saveman71
Copy link

So this will be a little long since I think I have to give some context. I'm writing this for posterity and for anyone who suffers the same problem I will describe.

Since my firsts steps with LoopBack, I experienced intermittent issues with user persistence in my app. The problem would just not make sense: the user could log in correctly, but after some time, the user would have to log in again, although I could confirm that the token was still saved in the shared preference of the SDK.
Worse, I could not reproduce the problem. No idea where to go from there, and why this could happen. After I had reviewed my code several times, I began to suspect that the SDK itself was causing the issue, but again, I wasn't able to even start debugging the problem (not reproducible, remember?).
The application being a launcher type app, it has a very long lifecycle, increasing the difficulty of isolating the problem.

So, thinking it was an isolated problem that only some users had, I pursued developing the app, until, at some point, I had to write some code that refreshed the user object to check for newly added props added server-side. It was working perfectly on my emulator and my phone. The day following the release, we had multiple user reports that the application was non-functional, and I had to revert my changes in a hurry.

There. I finally had something to work with. I began suspecting the differences between the debug and release builds, so I developed a rapid proof-of-concept app, and I was able to reproduce the issue. Hurray!

Here it is: saveman71/strongloop-sdk-android-proguard-poc

I was then able to finally pinpoint the issue down to these lines in UserRepository, where an AccessToken model, is created from the JSON response from the API. The issue is that the createObject method ultimately uses BeanUtil, to set the properties (here the userId) by using reflexion and calling the appropriate methods for each value in the JSON response, here that would be AccessToken.setUserId().

However, and that's why I wasn't able to reproduce the issue, I'm using proguard to obfuscate the release code that's being published on Google Play. This results in methods and attributes being renamed to very basic names, like a, b, etc. So now BeanUtil is looking for A.setUserId(), whereas the actual method has been obfuscated to something like A.a(), and it fails silently. (expected behaviour in a way, because you can't throw an error for every JSON property that doesn't have its corresponding setter)

All that to say, that there is NEVER, ever, some indication about such behaviour, nor any documentation about how to configure Proguard if we use the SDK.

Finally, the solution was to add the following lines to your proguard-rules.pro file:

-keepclassmembers class * extends com.strongloop.android.loopback.Model {
    public <methods>;
}

This literally says: "Do not obfuscate methods and members that are from classes extending Model"

This problem should really be documented somewhere since I believe (I may be mistaken about this) that Proguard is widely used in production use, and that every library should be aware of issues that code obfuscating could cause to their codebase.

Sorry about the excessively long issue, but I felt like I had to speak my mind about that, no hard feelings, happy to report back to the open source community, so that no one spends an other day debugging that!

@bajtos
Copy link
Contributor

bajtos commented May 10, 2016

@saveman71 Hello, thank you for reporting this issue and providing such detailed information! I agree we should at least capture this in our documentation. @crandmck could you PTAL?

It makes me wonder, how do other JSON serializers cope with obfuscation? Would it make sense to switch our implementation to use a 3rd party library instead of maintaining our own BeanUtil?

@bajtos bajtos added the doc label May 10, 2016
@bajtos bajtos assigned crandmck and unassigned bajtos May 10, 2016
@crandmck crandmck removed their assignment Jan 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants