Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.VerifyError IllformedLocaleException

I have the following parent method, that is used in all cases by various API levels:

public int setVoice (@NonNull final String language, @NonNull final String region){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        return setVoice21(language, region);
    } else {
        return setVoiceDeprecated(language, region);
    }
}

and setVoice21 does something like this:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public int setVoice21 ( @NonNull final String language, @NonNull final String region){

    try {
        // try some API 21 stuff
    } catch (final IllformedLocaleException e) {
        e.printStackTrace();
        return setVoiceDeprecated(language, region);
    }

setVoice21 contains other code that requires API 21+ specifically TextToSpeech.Voice and Locale.Builder

When I run this code on a device < API 21 I'm getting the following error:

W/dalvikvm: VFY: unable to resolve exception class 6232 (Ljava/util/IllformedLocaleException;) W/dalvikvm: VFY: rejecting opcode 0x0d at 0x0168 W/dalvikvm: VFY: rejected Lcom/myapp/android/speech/MyTextToSpeech;.setVoice21 (Ljava/lang/String;Ljava/lang/String;)I W/dalvikvm: Verifier rejected class Lcom/myapp/android/speech/MyTextToSpeech;

E/AndroidRuntime: FATAL EXCEPTION: main java.lang.VerifyError: com/myapp/android/speech/MyTextToSpeech

If I remove the IllformedLocaleException and just replace it with a standard Exception, the app runs fine, despite the many other references to methods > API21 within setVoice21

To confuse me yet further, setVoice21 invokes the following class

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private class TTSVoice {

    public void buildVoice() {

        try {
            // Do some API 21 stuff
        } catch (final IllformedLocaleException e) {
        }

    }
}

This class is only referenced from setVoice21, but I do not have to remove the reference to IllformedLocaleException here - I can leave it and the app runs fine.... Baffled.

Can anyone help me out as to why the IllformedLocaleException is causing this failure? Are Exceptions somehow handled differently?

I thank you in advance.

Note - I'm not sure that it is relevant, but I'm subclassing TextToSpeech in a standard way. I fear this may convolute the question, but just in case...

public class MyTextToSpeech extends TextToSpeech {

    public MyTextToSpeech(final Context context, final OnInitListener listener) {
        super(context, listener);
    }
}

EDIT - The workaround provided by razzledazzle below, does allow the app to run without crashing, but I still remain non-the-wiser as to why such a step is necessary. I've never had to take such measures before when dealing with API versioning.

like image 219
brandall Avatar asked Apr 13 '16 22:04

brandall


People also ask

What is linkageerror and verifyerror in Java?

Furthermore, the LinkageError class extends the Error class, which is used to indicate those serious problems that an application should not catch. A method may not declare such errors in its throw clause, because these errors are abnormal conditions that shall never occur. Finally, the VerifyError exists since the 1.0 version of Java.

What is a verifyerror in Java?

VerifyError means that the class file contains bytecode that is syntactically correct but violates some semantic restriction e.g. a jump target that crosses method boundaries. Basically, a VerifyError can only occur when there is a compiler bug, or when the class file gets corrupted in some other way (e.g. through faulty RAM or a failing HD).

Why do I get verifyerror when compiling?

Basically, a VerifyError can only occur when there is a compiler bug, or when the class file gets corrupted in some other way (e.g. through faulty RAM or a failing HD). Try compiling with a different JDK version and on a different machine. Show activity on this post.

Why does Java verification fail on my code?

In many cases, verification fails on valid, non-malicious bytecode because a newer version of Java has a stricter verification process than older versions. For example, JDK 13 may have added a verification step that was not enforced in JDK 7.


1 Answers

Resolved the issue by removing the IllformedLocaleException class from the catch argument. This will still allow you to check for IllformedLocaleException.

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public int setVoice21 (@NonNull final String language, @NonNull final String region) {
    try {
        // try some API 21 stuff
        ...
    } catch (final Exception e) {
        e.printStackTrace();
        if (e instanceof IllformedLocaleException) {
            ...
        }
    }

    ...
}
like image 136
razzledazzle Avatar answered Oct 13 '22 01:10

razzledazzle