0

Hey I am trying to use Google Cloud Speech API into Android but I am getting this error and am unable to get around it.

java.lang.VerifyError: Verifier rejected class com.google.cloud.speech.v1
  .StreamingRecognizeResponse due to bad method java.lang.Object com.google
  .cloud.speech.v1.StreamingRecognizeResponse.dynamicMethod(com.google.protobuf
  .GeneratedMessageLite$MethodToInvoke, java.lang.Object, java.lang.Object) 
  (declaration of 'com.google.cloud.speech.v1.StreamingRecognizeResponse' 
  appears in /data/app/com.curieo.podcast-1/base.apk:classes65.dex)

  at com.google.cloud.speech.v1.StreamingRecognizeResponse.getDefaultInstance(StreamingRecognizeResponse.java:1095)
  at com.google.cloud.speech.v1.SpeechGrpc.<clinit>(SpeechGrpc.java:67)
  at com.curieo.podcast.ui.fragment.dates.googlecloud.StreamingRecognizeClient.<init>(StreamingRecognizeClient.java:57)
  at com.curieo.podcast.ui.fragment.dates.googlecloud.MicrophoneStreamRecognizeClient.<init>(MicrophoneStreamRecognizeClient.java:54)
  at com.curieo.podcast.ui.fragment.dates.RecordFragment$1.run(RecordFragment.java:112)

I searched for this but couldn't find a solution. here is the code where error occurs

private Thread runner = new Thread() {

    public void run() {

        try {
            MicrophoneStreamRecognizeClient client;
            synchronized (this) {
                try {
                    client = new MicrophoneStreamRecognizeClient(getResources().openRawResource(R.raw.credential), Self); //crashes here 
                    client.start();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
};

Here is the code snippet of MicrophoneStreamRecognizeClient class:

public class MicrophoneStreamRecognizeClient {

private String host = "speech.googleapis.com";
private Integer port = 443;
private ManagedChannel channel;
private StreamingRecognizeClient client;

private final List<String> OAUTH2_SCOPES = Arrays.asList("https://www.googleapis.com/auth/cloud-platform");

/**
 *
 * @param authorizationFile
 * @param host
 * @param port
 * @return
 * @throws IOException
 */
 private ManagedChannel createChannel(InputStream authorizationFile, String host, int port) throws IOException {

    GoogleCredentials creds = GoogleCredentials.fromStream(authorizationFile);
    creds = creds.createScoped(OAUTH2_SCOPES);
    return ManagedChannelBuilder.forAddress(host, port)
        .intercept(new ClientAuthInterceptor(creds, Executors.newSingleThreadExecutor()))
        .build();
}

/**
 *
 * @param autorizationFile
 * @throws IOException
 */
 public MicrophoneStreamRecognizeClient(InputStream autorizationFile, IResults screen) throws IOException {

    channel = createChannel(autorizationFile, host, port);
    client = new StreamingRecognizeClient(channel, screen);
}

/**
 *
 * @throws IOException
 * @throws InterruptedException
 */
 public void start() throws IOException, InterruptedException {

    client.recognize();
}

/**
 *
 * @throws InterruptedException
 */
 public void stop() throws InterruptedException {

    client.shutdown();
}

}
Saransh Agarwal
  • 305
  • 5
  • 18
  • can you share MicrophoneStreamRecognizeClient class declaration? –  Oct 02 '17 at 07:20
  • do you extends any class? Not clear! where you get shutdown() and recognize()? –  Oct 02 '17 at 09:59
  • You can check this [link](https://github.com/Cloudoki/android-google-cloud-speech-api). It shows the full example. @EnamulHaque – Saransh Agarwal Oct 02 '17 at 10:38
  • Try a [different StreamingRecognizeClient build](https://github.com/yurifariasg/android-google-speech-sample/blob/master/GSpeechSample/app/src/main/java/me/yurifariasg/StreamingRecognizeClient.java) – Tudormi Nov 27 '17 at 10:31

2 Answers2

0

Cleaning out the build folder resolved the problem. Not sure why ART had an issue but Dalvik did not.

Running a gradle clean task was not clearing out my build folder all the way. I had to do it manually, but clean may work for some people.

Reference

java.lang.VerifyError can happen for some reason:

  1. A class tries to extend a class declared as final

  2. A method tries to override a super method that is declared as final

  3. A wrong argument is passed to a method

     clint = new MicrophoneStreamRecognizeClient(getResources()
             .openRawResource(R.raw.credential), Self); //crashes here 
    

I don't know what is Self. Is that ok?

Try this.

  synchronized (this) {
     MicrophoneStreamRecognizeClient client;
     try {
        client = new MicrophoneStreamRecognizeClient(getResources().openRawResource(R.raw.credential), Self); //crashes here 
         client.start();
     } catch (InterruptedException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

Because another issue can be !! Synchronized block inside try / catch block !! cause of java.lang.VerifyError reference

0

If the java.lang.VerifyError is triggered because library differences between runtime and compiling, as @Enamul also suggested, then you might wanna check differences between com.google.cloud.speech.v1.StreamingRecognizeResponse and com.google.cloud.speech.v1beta1.StreamingRecognizeResponse.

Even so, try with the beta, newer, version of the library. The example that inspired you uses the beta version.

Tudormi
  • 1,092
  • 7
  • 18
  • was this the case, @Saransh, have you tried using the [`com.google.cloud.speech.v1beta1.StreamingRecognizeResponse`](http://googleapis.github.io/googleapis/java/grpc-google-cloud-speech-v1beta1/0.1.5/apidocs/com/google/cloud/speech/v1beta1/StreamingRecognizeResponse.html) version? – Tudormi Dec 04 '17 at 08:46