Skip to content

Instantly share code, notes, and snippets.

@mattsilber
Last active July 31, 2020 17:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattsilber/125222f40597a1118cb34f296d3b8508 to your computer and use it in GitHub Desktop.
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)
/*
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();
}
@avipars
Copy link

avipars commented Jul 31, 2020

Did you find the solution?

@mattsilber
Copy link
Author

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