Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "Could not find policy 'pick_first'" with Google TTS java client?

I can't make a request using Google TTS Client library in java. Each time it throws a bunch of exceptions.

I just try to get a list of available voices.

    GoogleCredentials creds = null;
    TextToSpeechClient textToSpeechClient = null;
    try {
        creds = GoogleCredentials.fromStream(new FileInputStream(credsFile));
        TextToSpeechSettings settings = TextToSpeechSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(creds)).build();
        textToSpeechClient = TextToSpeechClient.create(settings);
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(-2);
    }

    if (cmd.hasOption('l')) {
        ListVoicesRequest request = ListVoicesRequest.getDefaultInstance();
        ListVoicesResponse response = textToSpeechClient.listVoices(request);
        List<Voice> voices = response.getVoicesList();
        System.out.println("Available voices :");
        for (Voice v : voices) {
            System.out.printf(" - %s, [%d]: %s/%s", v.getName(), v.getLanguageCodesCount(), v.getLanguageCodes(0), v.getSsmlGender());
        }
        textToSpeechClient.close();
        System.exit(0);
    }

I first thought it came from the credentials file. But it's not, the file is correctly located.

And I get this.

avr. 02, 2019 11:36:46 PM io.grpc.internal.ManagedChannelImpl$1 uncaughtException
SEVERE: [Channel<1>: (texttospeech.googleapis.com:443)] Uncaught exception in the SynchronizationContext. Panic!
java.lang.IllegalStateException: Could not find policy 'pick_first'. Make sure its implementation is either registered to LoadBalancerRegistry or included in META-INF/services/io.grpc.LoadBalancerProvider from your jar files.
        at io.grpc.internal.AutoConfiguredLoadBalancerFactory$AutoConfiguredLoadBalancer.<init>(AutoConfiguredLoadBalancerFactory.java:93)
        at io.grpc.internal.AutoConfiguredLoadBalancerFactory.newLoadBalancer(AutoConfiguredLoadBalancerFactory.java:64)
        at io.grpc.internal.ManagedChannelImpl.exitIdleMode(ManagedChannelImpl.java:357)
        at io.grpc.internal.ManagedChannelImpl$ChannelTransportProvider$1ExitIdleModeForTransport.run(ManagedChannelImpl.java:455)
        at io.grpc.SynchronizationContext.drain(SynchronizationContext.java:101)
        at io.grpc.SynchronizationContext.execute(SynchronizationContext.java:130)
        at io.grpc.internal.ManagedChannelImpl$ChannelTransportProvider.get(ManagedChannelImpl.java:459)
        (...) a whole bunch of other lines

How to fix this error ?

Note that I'm using the latest google-cloud-texttospeech library (version 0.85.0-beta).

like image 604
Gui-Yôm Avatar asked Apr 02 '19 21:04

Gui-Yôm


3 Answers

If you're using Gradle with the ShadowJar plugin, this is all you need to get it to merge the contents of service files from the various gRPC libraries:

shadowJar {
    mergeServiceFiles()
}

Discovered from a thread here.

like image 70
Doug Stevenson Avatar answered Nov 11 '22 01:11

Doug Stevenson


Another solution. Hope can help somebody.

Problem is the package name of io.grpc.INTERNAL.PickFirstLoadBalacerProvider class. Insert below code lines before you use grpc.

import com.google.cloud.internal.PickFirstLoadBalancer;
...
LoadBalancerRegistry.getDefaultRegistry().register(new PickFirstLoadBalancerProvider());

LoadBalancerProviders are registered at map in the LoadBalancerRegistry and key of map is the name of class (not exactly but does not matter). So LoadBalancerRegistry returns newly registered class to the grpc.

like image 44
Youngrok Ko Avatar answered Nov 11 '22 01:11

Youngrok Ko


The io.grpc library registers classes from a file in your META-INF/services.

So, create a file named io.grpc.LoadBalancerProvider in that folder with the content:

io.grpc.internal.PickFirstLoadBalancerProvider

The library should find the class that way.

like image 7
dhontecillas Avatar answered Nov 11 '22 00:11

dhontecillas