After an update of Dexguard from 7.0.12 to 7.1.22, I'm encountering a crash on an Enum switch.
This only happens when Dexguard has run on our project (I suppose this is caused by a Proguard issue).
If I use hardcoded values, the crash does not occur.
Ofcourse, I want to avoid using hardcoded values.
The crash that occurs is the following
java.lang.NoClassDefFoundError: Failed resolution of: Lif;
This occurs on the line that states switch(type) {
(see below)
Some example code on which the app crashes (given that MyEnum is an Enum ofcourse):
MyEnum type = MyEnum.SomeValue;
switch (type) {
case SomeValue:
// Do something
Log.i("Tag", "Hello world!");
break;
}
Assume that the ordinal value of MyEnum.SomeValue
is 1.
If I change case SomeValue:
to case 1:
it works like expected.
I do not know why this crash occurs. I have tried to add these Proguard rules.
-keep enum * { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
But this does not fix the issue.
I just checked the mapping file, all of my enum names etc are kept. Now I'm even more clueless of what's happening.
my.identifier.MyEnum -> my.identifier.MyEnum:
my.identifier.MyEnum SomeValue -> SomeValue
my.identifier.MyEnum[] $VALUES -> $VALUES
6:6:my.identifier.MyEnum[] values() -> values
6:6:my.identifier.MyEnum valueOf(java.lang.String) -> valueOf
6:6:void <init>(java.lang.String,int) -> <init>
6:7:void <clinit>() -> <clinit>
Just took a look at the output. It's compiled to this.
Judging on the stack trace, I suppose if
is not kept by Proguard.
Where is this defined? what do I need to add to make Proguard keep this?
switch(if.ˊ[var2.ordinal()]) {
case 1:
//some other code
break;
In the intermediates that line of code looks like this:
switch(null.$SwitchMap$my$identifier$MyEnum[type.ordinal()]) {
case 1:
//some other code
break;
the fact that it states null.$
bothers me. That does not seem right. or is that normal?
Just reverted to our older version of Dexguard and removed the Proguard rules I added.
The crash does not occur anymore now, although the code still looks exactly the same. (The intermediates AND the fully compiled code)
Switched over to Dexguard 7.2 and it went flawless.
The switch statement will create a synthetic inner class with an array field $SwitchMap$MyEnum
mapping the ordinal of the enum field to an integer greater than 0. You need to make sure this class and it field are preserved as well.
I got the same problem. When i decompile the class i see question marks (??? should be arg0 in this case)
public static cr a(String arg0)
{
switch (???)
{
case "caseOne":
??? = a;
break;
case "caseTwo":
??? = f;
break;
default:
??? = null;
}
return (cr)???;
}
if you reassign the argument internally like
arg0= arg0.toLowerCase();
then proguard understands what to put instead of the question marks
public static cr a(String paramString)
{
switch (paramString = paramString.toLowerCase())
{
case "caseOne":
paramString = a;
break;
case "caseTwo":
paramString = f;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With