如何使用Google TTS Java客户端修复“找不到策略'pick_first'”?

时间:2019-04-02 21:48:55

标签: java google-text-to-speech

我无法使用Java中的Google TTS客户端库发出请求。每次它抛出一堆异常。

我只是尝试获取可用声音的列表。

    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);
    }

我首先认为它来自凭证文件。但这不是,文件位置正确。

我明白了。

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

如何解决此错误?

请注意,我正在使用最新的google-cloud-texttospeech库(版本0.85.0-beta)。

4 个答案:

答案 0 :(得分:3)

如果您将Gradle与ShadowJar插件一起使用,则只需要将其合并即可合并来自各种gRPC库的服务文件的内容:

shadowJar {
    mergeServiceFiles()
}

从线程here中发现。

答案 1 :(得分:1)

io.grpc库在您的META-INF/services中的文件中注册类。

因此,在该文件夹中创建一个名为io.grpc.LoadBalancerProvider的文件,内容如下:

io.grpc.internal.PickFirstLoadBalancerProvider

库应该以这种方式找到该类。

答案 2 :(得分:0)

您还可以在io.grpc.LoadBalancerProvider中创建多个条目。对于Google的Pub/Sub库(Google Chat bot消息传递中间件),我看到以下内容:

io.grpc.grpclb.GrpclbLoadBalancerProvider
io.grpc.internal.PickFirstLoadBalancerProvider
io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider

如果要创建一个胖/带阴影的罐子,则多个条目是一个问题,因为这些条目会相互覆盖。

答案 3 :(得分:0)

另一种解决方案。希望能帮到人。

问题是io.grpc.INTERNAL.PickFirstLoadBalacerProvider类的包名。 在使用 grpc 之前插入下面的代码行。

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

LoadBalancerProviders 在 LoadBalancerRegistry 中的地图上注册,地图的键是类的名称(不完全但无关紧要)。所以 LoadBalancerRegistry 将新注册的类返回给 grpc。