Menu

#367 AbstractMethodError with -allowaccessmodification

v6.2
closed-fixed
None
High
2019-12-06
2010-07-01
No

I ran into a bug with -allowaccessmodification and -repackageclasses. Basically if you have an abstract super class ("ClassA") that has a package-level (default) visible abstract method, and you have two sub classes "ClassB" and "ClassC", and you instruct ProGuard to -keep class some.pkg.ClassC { *; }, then something gets fubared up and when running the code, you'll get an AbstractMethodError.

"fubared" is a bit imprecise. To me it appears the byte code (as reported by javap) is legitimate, but apparently I'm wrong.

I have attached a reproducible setup. Run "sh test.sh" to see the error. Be careful just to run it in the right directory, as "test.sh" does a rm -r bin at some point. It is looking for a proguard.jar in subdirectory lib.

Another weird thing is that in my larger project exhibiting the bug, the byte code is obviously wrong. ClassA and ClassC keep the original method name (no obfuscation), but in ClassB all method names get obfuscated, and I obviously get an abstract method error. In the attached reproducible case, the byte code looks ok if you ask me (but I'm clueless about that), and you actually get an AbstractMethodError when calling the method of ClassC.

Discussion

  • Anonymous

    Anonymous - 2010-07-01

    Reproducible test case for the AbstractMethodError

     
  • Eric Lafortune

    Eric Lafortune - 2010-07-01

    Thanks for the detailed report. I can reproduce the problem. ClassC can no longer override the package visible method bar of the repackaged ClassA, which causes the AbstractMethodError. I'll have to figure out why the method isn't made public, and then fix it.

     
  • Eric Lafortune

    Eric Lafortune - 2010-07-01
    • assigned_to: nobody --> lafortune
    • priority: 5 --> 7
     
  • Zhenya

    Zhenya - 2010-12-06

    We are experiencing the same problem. We'll appreciate if it is fixed as soon as possible. Thanks.

     
  • Christian Schlichtherle

    I just ran into this problem with an enum class using ProGuard 4.8.

    Assume the following (drafting from my head, so please bear with me on any errors):

    package foo;
    
    public enum Bar {
        A {
            @Override void run() {
                System.out("Hello world!");
            }
        };
    
        abstract void run();
    
        public static void main(String[] args) {
            A.run();
        }
    }
    

    Now with the following configuration:

    -repackageclasses
    -allowaccessmodification
    -keepclasseswithmembers public class * {
        public static void main(java.lang.String[]);
    }
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    

    ... I get an AbstractMethodError when running foo.Bar.main(null). I've inspected the obfuscated byte code with ASMifier and could verify that the generated byte code is correct, except that the access modifier for the renamed run() method is kept at default. Now the class Bar is still within the package foo, but the singleton enum class A is renamed and moved into the default package. Because of the different packages, the abstract method in the super class foo.Bar can't get overridden by the renamed and moved singleton enum class A anymore.

    As a workaround, I need to declare the run() method protected (and of course, it's implementation in the enum class A.

     
  • Eric Lafortune

    Eric Lafortune - 2013-02-04

    Christian, thanks for the example. I can reproduce the problem, but I still need to fix it (it has slipped through so far).

     
  • Christian Schlichtherle

    I tested this issue again and it seems to be fixed. I was using ProGuard 5.1 for the test. Maybe you can close this issue?

     
  • T. Neidhart

    T. Neidhart - 2019-12-06
    • status: open --> closed-fixed
    • Group: --> v6.2
    • Priority: 7 --> High
     
  • T. Neidhart

    T. Neidhart - 2019-12-06

    Tested the sample also with the latest version 6.2.0 and it works fine.

     

Log in to post a comment.