includedescriptorclasses does not keep type parameters
Java class file shrinker, optimizer, obfuscator, and preverifier
Brought to you by:
guardsquare
Repro steps:
1) Create class:
import java.util.List;
public interface ApiStub {
public List<Pojo> get();
}
2) Create proguard config
-keep,includedescriptorclasses public class ApiStub { *; }
-whyareyoukeeping class Pojo
Expected result:
Pojo shoud be kept
Actual result:
Pojo is not kept
Tested with v5.2.1. If I change the method signature to public Pojo get();, then Pojo is kept as expected. It's possible that I'm misunderstanding what includedescriptorclasses is supposed to do.
Happy to attach a more complete repro environment if needed, thanks!
Also type parameter is changed to List<object> in the output jar like -
which results in ClassCastException at runtime.
</object>Last edit: Manish Goyal 2016-01-27
Generics in Java source code are erased in Java bytecode, so List<pojo> is actually just List as far as the JVM is concerned. The complete generic signature is still preserved in an attribute called Signature, for the sake of compilers and possibly reflection at runtime. You can preserve it with</pojo>
The modifier includedescriptorclasses currently doesn't extend to the contents of this attribute. I'm not sure if it would be very useful, but it probably wouldn't harm. For now, you can keep the attribute and you can still manually preserve the class as well:
Ya, we're currently working around this with an annotation processor that unrolls the relevant generics and feeds them to proguard.
How hard would it be to change the includedescriptorclasses logic to read the generic types from Signature?
Even this doesn't help us -
The expectation is that if we have a field such as -
there should be no need to explicitly use -
as class Pojo is in use and should not be shrinked.
Please go through this sample code to find more details -
https://github.com/manishgo/proguard_testing/blob/master/src/main/java/com/proguardtesting/Jungle.java
Last edit: Manish Goyal 2016-01-28
In src/proguard/ClassSpecificationVisitorFactory.java, at line 147, you can replace
by
This change will be included in DexGuard 5.3.