Menu

#603 Call to default super interface method is broken (StackOverFlowException) (invokespecial)

v5.2
open-works-for-me
None
5
2016-06-20
2016-05-09
No

I use the version 5.2.1. The follow call to a super interface default method:

@Override
public default <T> T unwrap( Class<T> clazz ) {
    return Bar.super.unwrap( clazz );
}

will result in follow bad code which produce a StackOverFlowException:

@Override
public default <T> T unwrap( Class<T> clazz ) {
    return unwrap( clazz );
}

With the javap disambler it look like:

// before ProGuard
public <t extends="" java="" lang="" object=""> T unwrap(java.lang.Class<t>);
Code:
0: aload_0
1: aload_1
2: invokespecial #1 // InterfaceMethod foo/Bar.unwrap:(Ljava/lang/Class;)Ljava/lang/Object;
5: areturn</t></t>

// after ProGuard
public <t extends="" java="" lang="" object=""> T unwrap(java.lang.Class<t>);
Code:
0: aload_0
1: aload_1
2: invokeinterface #4, 2 // InterfaceMethod foo/Bar.unwrap:(Ljava/lang/Class;)Ljava/lang/Object;
7: areturn</t></t>

Discussion

  • Volker Berlin

    Volker Berlin - 2016-05-09

    A workaround is the option:
    -dontoptimize

     
  • Eric Lafortune

    Eric Lafortune - 2016-05-16

    Thanks for your report. I can't seem to reproduce the issue yet (with a hierarchy of a class, a first interface, and a second interface). Can you provide the complete sample?

     
  • Eric Lafortune

    Eric Lafortune - 2016-05-16
    • status: open --> open-works-for-me
    • assigned_to: Eric Lafortune
     
  • Volker Berlin

    Volker Berlin - 2016-05-17

    Attached is a full sample with original compiled classes and obfuscated classes.

     
  • Eric Lafortune

    Eric Lafortune - 2016-05-22

    Thanks for the sample. I can see how your processed code is incorrect, but I get correct code with ProGuard 5.2.1 and the following configuration:

    -injars  classes
    -outjars out.jar
    -libraryjars <java.home>/lib/rt.jar
    
    -dontobfuscate
    
    -keep class test.MyTest {
        public static void main(java.lang.String[]);
    }
    

    What configuration are you using?

     
  • Volker Berlin

    Volker Berlin - 2016-05-30

    We use a mix of gradle properties and file settings. in gradle we set:
    configuration, printseeds, printmapping, printusage, keepparameternames,
    renamesourcefileattribute "SourceFile"
    keepattributes "Exceptions,InnerClasses,Deprecated,SourceFile,Signature,Annotation,LineNumberTable,EnclosingMethod"
    keeppackagenames "com.inet.**"

    In the configuration file we set:
    -dontusemixedcaseclassnames
    -keep @com.inet.annotations.PublicApi class * { public *; }

    And a long list of other keep settings.

     
  • Petar Tahchiev

    Petar Tahchiev - 2016-06-20

    Hello,

    I think i have similar problem. This is my code:

    @Transactional
    @Override
    public void importClasspathResource(@Nonnull String importId, @Nonnull String uri) throws CsvException {
        CsvInputProcessor.super.importClasspathResource(importId, uri);
    }
    

    and it gets obfuscated to this:

    @Transactional
    public void importClasspathResource(@Nonnull String importId, @Nonnull String uri) throws CsvException {
        this.importClasspathResource(importId, uri);
    }
    

    notice the call to the super default method is replaced to this method.

    How can I add make it work?

     
  • Petar Tahchiev

    Petar Tahchiev - 2016-06-20

    And I confirm that adding -dontoptimize works, but is this the real solution, or just a workaround?

     

Log in to post a comment.