-keepattributes Signature doesn't retain generic parameter types
Java class file shrinker, optimizer, obfuscator, and preverifier
Brought to you by:
guardsquare
I have a Retrofit service which defines the following:
@POST("/sign-out") // Observable<SignOutResponse> signOut( // @Body SignOutRequest request);
At the call site, however, the generic parameter type SignOutResponse
is never actually referenced:
appService.signOut(new SignOutRequest()) // .onErrorResumeNext(Observable.<SignOutResponse>empty()) // .subscribe();
This causes ProGuard to strip the type and ultimately cause a failure at runtime when Retrofit does reflection on the method return type in order to determine what type to use for deserialization.
Because -keepattributes Signature
is specified, I believe that ProGuard should be marking types used in as generic parameters as seeds to be retained. While it's highly unlikely that a generic type is specified and not referenced elsewhere except reflection, it can happen in some cases and ideally behaves in the least surprising way.
Thanks for your report. ProGuard preserves the class if it is clearly used (e.g. instantiated), but it indeed removes it otherwise (e.g. only deserialized throught reflection). This is consistent with the general behavior that reflection may require some configuration.
Automatically preserving all classes in Signature attributes would fairly randomly drag along other classes that occur in generic signatures, e.g. interface classes that are not really required. I'm reluctant to create worse results in general (and get complaints...), so this would have to be some sort of option. I'll have to think about it. For now, something like this should work:
Note that you still have the option to obfuscate the class name this way.
This is probably a duplicate of, or related to #482.