Last active
July 31, 2020 17:24
-
-
Save mattsilber/125222f40597a1118cb34f296d3b8508 to your computer and use it in GitHub Desktop.
Android java.lang.VerifyError Rejecting class * because it failed compile-time verification (declaration of * appears in /data/app/**-1/base.apk)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Notes: | |
gradleVersion = '2.14.1' | |
com.android.tools.build:gradle:2.2.3 | |
compileSdkVersion 25 | |
buildToolsVersion "25.0.2" | |
minSdkVersion 15 | |
targetSdkVersion 25 | |
*/ | |
private interface Region { | |
public String getName(); | |
} | |
public enum Country { | |
US, CA | |
} | |
public enum USState implements Region { | |
NEWYORK; | |
@Override | |
public String getName(){ | |
return name(); | |
} | |
} | |
public enum CanadianTerritory implements Region { | |
ONTARIO; | |
@Override | |
public String getName(){ | |
return name(); | |
} | |
} | |
private Country country = Country.US; | |
// Throws runtime VerifyError complaining about compile-time verification, even though | |
// both enums very clearly implement the Region interface | |
private Region[] getRegions(){ | |
if(country == Country.CA) | |
return CanadianTerritory.values(); | |
else | |
return USState.values(); | |
} | |
// Will NOT throw the VerifyError, but compiler warns of redundant casting | |
private Region[] getRegions(){ | |
if(country == Country.CA) | |
return (Region[]) CanadianTerritory.values(); | |
else | |
return (Region[]) USState.values(); | |
} | |
// Throws runtime VerifyError complaining about compile-time verification, even though | |
// both enums very clearly implement the Region interface | |
private Region[] getRegions(){ | |
switch(country){ | |
case CA: return CanadianTerritory.values(); | |
case US: | |
default: return USState.values(); | |
} | |
} | |
// Throws VerifyError with "bad method" message | |
private List<Region> getRegions(){ | |
List<Region> regions = new ArrayList<Region>(); | |
if(country == Country.CA) | |
regions.addAll(Arrays.asList(CanadianTerritory.values())); | |
else | |
regions.addAll(Arrays.asList(USState.values())); | |
return regions; | |
} | |
// Does NOT throw the VerifyError | |
private Region[] getRegions(){ | |
return country == Country.CA | |
? CanadianTerritory.values() | |
: USState.values(); | |
} | |
I filed a bug report back in 2017, but it was closed.
The only "solution" I've seen thus far is to specifically downcast to the interface type when returning the enum array, even though the compiler gives a redundancy warning. From the examples above, that would be:
// Will NOT throw the VerifyError, but compiler warns of redundant casting
private Region[] getRegions(){
if(country == Country.CA)
return (Region[]) CanadianTerritory.values();
else
return (Region[]) USState.values();
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did you find the solution?