Menu

#492 NoSuchMethodError (4.11 beta8)

v4.11
closed-fixed
nobody
None
5
2014-09-17
2013-12-12
Wanderer
No

The latest version of ProGuard, during the shrinking phase, removes methods that should not be removed. All settings have default values. I kept getting the following error messages:

Exception in thread "main" java.lang.NoSuchMethodError:
a.iterator()Ljava/util/Iterator; at Main.main(Unknown Source)

and finally managed to reduce the error-causing class into a small application. Please note the double inheritance in the interface. The ProGuard version is 4.11 beta8.

import java.util.*;

public class Main
{
  // Combined interface to allow anonymous iterable classes
  public interface AnonIterable extends Iterable, Iterator {}

  public static void main(String[] args)
  {
    AnonIterable iterable = new AnonIterable()
    {
      // Iterable method
      public Iterator iterator() { return this; }

      // Iterator methods
      public boolean hasNext() { return false; }
      public Object next() { return null; }
      public void remove() {}
    };

    iterable.iterator(); // Crashes with java.lang.NoSuchMethodError :(
  }
}

The anonymous inner class, new AnonIterable() {...}, after being processed by ProGuard, loses all its methods. Only empty constructor remains:

public final class a
{
    a()
    {
    }
}

Disabling obfuscation doesn't help. The weird thing is, disabling shrinking doesn't help either. The app still crashes with NoSuchMethodError, but the decompiled version of inner class becomes different:

public final class a
{
    a()
    {
    }

    private Iterator a()
    {
        return this;
    }

    private static boolean b()
    {
        return false;
    }

    private static Object c()
    {
        return null;
    }

    private static void d()
    {
    }
}

Apparently, any connection with the interface's method signatures gets lost at some point.

Discussion

  • Eric Lafortune

    Eric Lafortune - 2013-12-12

    Thanks for the report. This bug seems to have been fixed by a very recent correction in this area, which you can now find in ProGuard 4.11 beta9.

     
  • Wanderer

    Wanderer - 2013-12-13

    The new version fixes the problem, much thanks for the quick fix! :)

    The new version (4.11 beta9) works great, with one note: comparing to version 4.10, it produces quite some extra glue code. In certain cases, ProGuard generates a whole chain of extra assignments: d2 = d1; d3 = d2; d4 = d3 etc (each variable is used only once). While this may be good for obfuscation purposes, this is not perfect for optimization. But this is just a minor thing.

     
  • Eric Lafortune

    Eric Lafortune - 2013-12-27
    • status: open --> closed-fixed
     

Log in to post a comment.