2019/06/24

io.grpc.ManagedChannelProvider$ProviderNotFoundException が発生した時の対処方法

[Google Photos API](https://developers.google.com/photos/) の Java クライアントライブラリを使おうとしたところ、以下のようなエラーが出てしまいました。

```
io.grpc.ManagedChannelProvider$ProviderNotFoundException: No functional channel service provider found. Try adding a dependency on the grpc-okhttp, grpc-netty, or grpc-netty-shaded artifact
```

> Try adding a dependency on the grpc-okhttp, grpc-netty, or grpc-netty-shaded artifact

とのことなので `ManagedChannelProvider` の実装が必要なことはわかりました。
が、「どうやって指定するのよ…」と悩むこと小一時間。



### 解決方法
結論から言うと、特に Java のコードですることはなく、依存ライブラリを指定してやればよいだけでした。
例えば、gradle なら以下の1行を追加するだけですgrpc-netty 等でも大丈夫だと思いますが、未確認です。

```groovy
`highlight: 2;
dependencies {
    implementation 'io.grpc:grpc-okhttp:1.21.0'
}

```

結局、エラーメッセージの指示通りにすれば良かったというオチでした。


### リフレクションを使ってた
[ManagedChannelProvider](https://github.com/grpc/grpc-java/blob/v1.21.x/api/src/main/java/io/grpc/ManagedChannelProvider.java) のコードを見ると、`ManagedChannelProvider` の実装を実行時に探していることがわかります。


```java
`first-line: 37;
  private static final ManagedChannelProvider provider = ServiceProviders.load(
      ManagedChannelProvider.class,
      HARDCODED_CLASSES,
      ManagedChannelProvider.class.getClassLoader(),
      new PriorityAccessor() {
        @Override
        public boolean isAvailable(ManagedChannelProvider provider) {
          return provider.isAvailable();
        }

        @Override
        public int getPriority(ManagedChannelProvider provider) {
          return provider.priority();
        }
      });
```


### 最適化している場合は注意
上記のようにリフレクションを使っているので、
ProGuard 等で最適化している場合は grpc-okhttp を最適化対象から外しておかないといけません。


0 件のコメント: