Issue
ProGuard is unable to preserve class members when specified correctly.
Assume the following class:
package com.package.some;
class SomeClass {
void someMember() {
var someVariable = () => {};
}
}
Java compiled a synthetic class for the lambda. ProGuard moved it to another synthetic class, which was compiled for another class.
Solutions
The following rule for ProGuard solves this issue:
-keepclassmembernames ** {
*;
}
This solution is not practical, because it applies to any class due to the wildcard. The following rule solves the issue as well:
-keepclassmembernames class ** {
synthetic *** *(...);
}
Unfortunately, this solution is not practical as well, because it applies to unrelated classes as well. The following solution does not work:
-keepclassmembernames class com.package.some.**
Unfortunately, it is unknown why it does not.
References
- The issue has been discovered and discussed in this GitHub issue for a complete reference.
- The issue can be reproduced fully with the following steps:
- Clone git@github.com:revanced/revanced-integrations.git
- Checkout revision
3f5e27d6b16d7aa73eef2ffb201e9f462eb84487
- Run
./gradlew build
in the root directory and save the release apk file - Apply a working rule from Solutions above and build the project again
- Compare the release apk files:
- The release apk file differs for class
app.revanced.all.connectivity.wifi.spoof.SpoofWifiPatch
. - For class
app.revanced.integrations.patches.LithoBlockRegister
the synthetic classLithoBlockRegister$$ExternalSyntheticApiModelOutline0
contains code from classSpoofWifiPatch
when no rule from Solutions is applied.
- The release apk file differs for class