Menu

#591 includedescriptorclasses does not keep type parameters

v5.2
closed-fixed
None
5
2016-10-23
2016-01-26
No

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!

Discussion

  • Manish Goyal

    Manish Goyal - 2016-01-27

    Also type parameter is changed to List<object> in the output jar like -

    public interface ApiStub {
        public List<Object> get();
    }
    

    which results in ClassCastException at runtime.

    </object>
     

    Last edit: Manish Goyal 2016-01-27
  • Eric Lafortune

    Eric Lafortune - 2016-01-28

    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>

    -keepattributes Signature
    

    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:

    -keep class com.example.Pojo
    
     
  • Nicholas Santos

    Nicholas Santos - 2016-01-28

    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?

     
  • Manish Goyal

    Manish Goyal - 2016-01-28

    Even this doesn't help us -

    -keepattributes Signature
    

    The expectation is that if we have a field such as -

    public List<Pojo> get();
    

    there should be no need to explicitly use -

    -keep class com.example.Pojo
    

    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
  • Eric Lafortune

    Eric Lafortune - 2016-02-07

    In src/proguard/ClassSpecificationVisitorFactory.java, at line 147, you can replace

                {
                    memberVisitor,
                    new MemberDescriptorReferencedClassVisitor(classVisitor),
                });
    

    by

                {
                    memberVisitor,
    
                    new MemberDescriptorReferencedClassVisitor(classVisitor),
    
                    new AllAttributeVisitor(
                    new AttributeNameFilter(ClassConstants.ATTR_Signature,
                    new ReferencedClassVisitor(classVisitor)))
                });
    

    This change will be included in DexGuard 5.3.

     
  • Eric Lafortune

    Eric Lafortune - 2016-02-07
    • status: open --> open-fixed
    • assigned_to: Eric Lafortune
     
  • Eric Lafortune

    Eric Lafortune - 2016-10-23
    • Status: open-fixed --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB