When building against an obfuscated library (providing its mapping file using -applymapping), I have noticed that lambda expressions which represent an implementation of an interface do not get obfuscated correctly when that interface is part of the obfuscated library.
At runtime this produces an AbstractMethodError because the interface's single member method was renamed, but the lambda instance still has the unobfuscated method name.
Steps to Reproduce
The idea is to build an obfuscated library defining an interface and an application defining a lambda
lib_stripped.jar
Interface.java
interface Interface {
void doSomething(int x);
}
Lib.java
public class Lib {
public static void call(Interface i, int x) {
System.out.println("methods:");
for (var m : i.getClass().getDeclaredMethods()) {
System.out.println("\t" + m);
}
i.doSomething(x);
}
}
Now when we run this, we get an AbstractMethodError and see that the method defined on the passed object is still called doSomething:
$ java -cp lib_stripped.jar:app_stripped.jar Main
methods:
public void Main$$Lambda/0x000071a1e8001800.doSomething(int)
Exception in thread "main" java.lang.AbstractMethodError: Receiver class Main$$Lambda/0x000071a1e8001800 does not define or inherit an implementation of the resolved method 'abstract void a(int)' of interface a.
at b.a(Unknown Source)
at Main.main(Unknown Source)
Additional context
If you run with the unobfuscated jars, you get the expected output:
$ java -cp lib.jar:app.jar Main
methods:
public void Main$$Lambda/0x00007baadc001800.doSomething(int)
101
When building against an obfuscated library (providing its mapping file using
-applymapping
), I have noticed that lambda expressions which represent an implementation of an interface do not get obfuscated correctly when that interface is part of the obfuscated library. At runtime this produces anAbstractMethodError
because the interface's single member method was renamed, but the lambda instance still has the unobfuscated method name.Steps to Reproduce
The idea is to build an obfuscated library defining an interface and an application defining a lambda
lib_stripped.jar
Interface.java
Lib.java
lib.pro
To build
lib_stripped.jar
:app_stripped.jar
Main.java
app.pro
To build
app_stripped.jar
:Now when we run this, we get an AbstractMethodError and see that the method defined on the passed object is still called
doSomething
:Additional context
If you run with the unobfuscated jars, you get the expected output: