GoogleCloudPlatform
gcp
dataflow
CloudSpanner

Dataflow SDK 2.x for JavaでSpannerIOを使うとjava.lang.NoSuchFieldErrorエラーになる問題を回避する

タイトルの通りだけど、Dataflow SDK 2.2.0でCloud Spannerへのアクセスをしようとしたとき、良く分からないエラーが出たので調べたことと解決方法を備忘録的に記事にしておく

問題のエラー

Exception in thread "main" java.lang.NoSuchFieldError: internal_static_google_rpc_LocalizedMessage_fieldAccessorTable
        at com.google.rpc.LocalizedMessage.internalGetFieldAccessorTable(LocalizedMessage.java:82)
        at com.google.protobuf.GeneratedMessageV3.getDescriptorForType(GeneratedMessageV3.java:109)
        at io.grpc.protobuf.ProtoUtils.keyForProto(ProtoUtils.java:127)

いやしかし指定したフィールドちゃんとあるし。型も間違っていないはず。

原因

調べると、以下のissueにもあるように grpc-google-common-protos 0.1系におけるバグらしい
https://github.com/GoogleCloudPlatform/cloud-bigtable-client/issues/1225
Dataflow SDK 2.2.0で依存関係に含まれている grpc-google-common-protos が 0.1系であるのが原因のようだ

解決方法

grpc-google-common-protos の1.x系をpom.xmlに追加して0.1系を上書きする

    <dependency>
        <groupId>com.google.api.grpc</groupId>
        <artifactId>grpc-google-common-protos</artifactId>
        <version>1.0.0</version>
    </dependency>

依存関係の問題なのでSDKのバージョンが上がればそのうち修正されると思うけど