protobuf v26.0 と protobuf-java v4.26.0
protobuf v26.0 が 2024/03/14 にリリースされましたが、Java, PHP, C++, Ruby, Python には破壊的変更が含まれています。
他の言語は詳しく分かりませんが、Java ではかなり大きな変更が入っており、protobuf-java のメジャーバージョンが上がっていて v4.x となっています。(マイナーバージョンは、protobuf のバージョンと同期しています)
大きな問題点は、protoc v26 以降でコンパイルされたファイルは、protobuf-java v3.25 以下ではコンパイル・動作できず、v4.26 以降を利用する必要がある点です。
速報的に、Java でどう対処すれば良いかを書いておきます。
コンパイル時のエラー
コンパイル時にこんなエラーが出たら、それは protoc に対して protobuf-java のバージョンが古いからです。
エラー: パッケージcom.google.protobuf.RuntimeVersionは存在しません
com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
エラー: シンボルを見つけられません
com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
^
シンボル: クラス RuntimeVersion
場所: パッケージ com.google.protobuf
エラー: シンボルを見つけられません
if (!com.google.protobuf.GeneratedMessage.isStringEmpty(referenceId_)) {
^
シンボル: メソッド isStringEmpty(Object)
場所: クラス GeneratedMessage
エラー: クラス com.google.protobuf.GeneratedMessage.Builder<BuilderType>のメソッド parseUnknownFieldは指定された型に適用できません。
if (!super.parseUnknownField(input, extensionRegistry, tag)) {
^
期待値: CodedInputStream,com.google.protobuf.UnknownFieldSet.Builder,ExtensionRegistryLite,int
検出値: CodedInputStream,ExtensionRegistryLite,int
理由: 実引数リストと仮引数リストの長さが異なります
BuilderTypeが型変数の場合:
クラス com.google.protobuf.GeneratedMessage.Builderで宣言されているBuilderType extends com.google.protobuf.GeneratedMessage.Builder<BuilderType>
対処方法
.proto
をコンパイルする protoc と、protobuf-java のバージョンが違うことにより発生する問題なので、両方のバージョンを互換性のあるバージョンに合わせれば問題ありません。
ツールによっては、protoc を常に最新版で利用するようになっていたり、brew upgrade
した途端にローカルの protoc が上がってしまったとか、のような状況で問題が発生することでしょう。
基本的には、以下のどちらかの方法を取ることになります。
protoc のバージョンを固定する
当面の間は、ライブラリの依存関係等もあるので protoc を v25 系以下で動かしたいところです。
どのように protoc を利用しているかによりますが、protobuf-gradle-plugin では以下のようにバージョンが固定できます。
protobuf {
...
// Configure the protoc executable
protoc {
// Download from repositories
artifact = 'com.google.protobuf:protoc:3.25.1'
}
...
}
buf を使っている場合でも、buf.gen.yaml
に以下のようにバージョンを指定することができます。
version: v1
plugins:
- plugin: buf.build/protocolbuffers/java:v25.1
out: java
- plugin: buf.build/protocolbuffers/kotlin:v25.1
out: kotlin
protobuf-java バージョンを上げる
protobuf-java (com.google.protobuf:protobuf-java
) を v4.26 以降に上げれば、protoc も v26.0 以降を使うことができます。
ただし、リリース直後の現在では protobuf に依存する他のライブラリも v4.26 以降に対応していない可能性があるので、注意。
将来的には、両方 v26 以降を利用できる環境を構築するべきでしょう。
まとめ
gRPC とかで、コンパイル済みのクライアントライブラリを jar にして共有 or maven publish しているとかの場合、protobuf に今回のような破壊的変更が加わると大変そう。