Menu

#537 shrink remove generics information with Java 8

v5.0
closed-fixed
None
8
2014-10-28
2014-08-25
dalmaso
No

If you extend a class defined in a JAR compiled with Java 8 and obuscated with "library.pro" (included in proguard5 dist), the generics type is not kept if shrink is enabled.
Workaround: use -dontshrink

== library
public class Foo<T> {
protected T value;

public T getValue() {
    return value;
}

public void setValue(T value) {
    this.value = value;
}

}

== application
public class Bar extends Foo<String> {

public int getLength() {
    return value.length();
}

}

== compilation error
C:\TestApp\src\testapp\Bar.java:12: error: cannot find symbol
return value.length();
symbol: method length()
location: variable value of type Object

Discussion

  • Hendrik Schreiber

    Thanks dalmaso for filing this bug.
    I wasted a lot of time unsuccessfully fooling around with -keepattributes options.

    There's a working workaround, but I'd still be all for increasing the prio on this.

     
  • Eric Lafortune

    Eric Lafortune - 2014-08-27

    Thanks for the report. This indeed appears to be a fairly serious bug introduced in 5.0: the shrinking step removes some signatures that should be preserved. I'll fix it for the next release.

     
  • Eric Lafortune

    Eric Lafortune - 2014-08-27
    • status: open --> open-accepted
    • assigned_to: Eric Lafortune
    • Priority: 5 --> 8
     
  • Hendrik Schreiber

    Great.
    Thanks!

     
  • Adam Bartoszewicz

    I have a similar problem, but I'm not sure if this is the same:

    public class J8ProGuardGenerics {
        public static void main(String[] args) {
            Interface1 o = new J8PG();
    
            System.out.println("before setObjectValue");
    
            //--- this line is not excecuted after obfuscation 
            //--- workaround: -dontshrink 
            o.setObjectValue("setObjectValue");
    
            System.out.println("after setObjectValue");
        }
    
        public static interface Interface1 {
            public void setObjectValue(Object value);
        }
    
        public static interface Interface2<Type> extends Interface1 {
            void setValue(Type value);
            @SuppressWarnings("unchecked")
            default public void setObjectValue(Object value) {
                setValue((Type)value);
            }
        }
    
        public static class J8PG implements Interface2<String> {
            @Override
            public void setValue(String value) {
                System.out.println(value);
            }
        }
    }
    

    Regards
    Adam

     
    • Eric Lafortune

      Eric Lafortune - 2015-01-13

      Adam, the bug that you reported had a different cause, but it has been solved in ProGuard 5.1 beta1.

       
  • Hendrik Schreiber

    Any progress on this?

     
  • Eric Lafortune

    Eric Lafortune - 2014-10-27
    • Status: open-accepted --> closed-fixed
     
  • Hendrik Schreiber

    Awesome! Looking forward to trying this out.

     
  • Adam Bartoszewicz

    I checked my case, described above ( https://sourceforge.net/p/proguard/bugs/537/#62a5 )
    It seems that the problem still exists.

     
  • Adam Bartoszewicz

     
  • Hendrik Schreiber

    The fix seems to work for me.

     
  • dalmaso

    dalmaso - 2014-10-28

    Works for me, too!
    Tested with my example in the first post.

     

Log in to post a comment.