Bug: method name used used as provider-key is very error prone. #96
Description
Problem
We use Proguard to obfuscate our code, last week we had a major issue in a production version of our app. After investigating we found an issue that was caused by Proguard, which converted two methods with different names to two methods with equal names (which is exactly what Proguard should do).
Before Proguard:
interface Cache {
Observable<List<ObjectA>> listObjectA(Observable<List<ObjectA>> observable, DynamicKey dynamicKey, EvictProvider evictProvider);
Observable<List<ObjectB>> listObjectB(Observable<List<ObjectB>> observable, DynamicKey dynamicKey, EvictProvider evictProvider);
}
After Proguard (simplified for the sake of the example):
interface Cache {
Observable<List<ObjectA>> a(Observable<List<ObjectA>> observable, DynamicKey dynamicKey, EvictProvider evictProvider);
Observable<List<ObjectB>> a(Observable<List<ObjectB>> observable, DynamicKey dynamicKey, EvictProvider evictProvider);
}
After Proguard the method names are the same: a
(this is totally valid Java code!). This is a problem as RxCache currently uses the method name as provider key. This leads to ugly run-time ClassCastExceptions
because two providers use the same provider-key (and thus use the same "space" in Memory).
Dirty solution
To prevent this we can either keep the Cache
class using the following Proguard rule:
-keep class org.example.Cache { *; }
Proposed solution
But it would be way nicer if we can manually provide the provider key using an Annotation, as we don't use Proguard for nothing (we want the names to be non-readable). This also enables us to change the method names without writing a migration.
Example:
interface Cache {
@ProviderKey("some-key-for-list-a")
Observable<List<ObjectA>> listObjectA(Observable<List<ObjectA>> observable, DynamicKey dynamicKey, EvictProvider evictProvider);
@ProviderKey("some-key-for-list-b")
Observable<List<ObjectB>> listObjectB(Observable<List<ObjectB>> observable, DynamicKey dynamicKey, EvictProvider evictProvider);
}
Impact
Modifying the ProxyTranslator.getProviderKey()
should be very simple and straightforward, it also wont impact other components of RxCache like migration.
Remarks
- If for some good reason this change is rejected at least make sure the Proguard section of the documentation is complete and includes a warning!
- Another way to fix this is to use the full method signature (not only the name but also the argument types and return types etc.) But this will probably break migration and some other components and is thus not fit for the job.
Let me know what you think, I'm willing to create a pull-request for the proposed changes!