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.
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.
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).
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.
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.
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) {
...
}
}
...
}
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