Java版gRPCのクライアントのメモ。
protoファイルのビルドしてgRPCクライアントを作成するために、build.gradleに以下のように設定する。[2026-06-13]
plugins {
id 'java'
id 'application'
id 'com.google.protobuf' version '0.9.5'
}
group = 'com.example.grpc'
repositories {
mavenCentral()
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
}
def grpcVersion = '1.81.0'
def protobufVersion = '3.25.8'
def protocVersion = protobufVersion
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
}
generateProtoTasks {
all()*.plugins { grpc {} }
}
}
application {
applicationName = 'grpc-example-client'
mainClass = 'com.example.grpc.client.GrpcExampleClient'
}
protobufタスクは、デフォルトではsrc/main/protoにあるprotoファイルがビルド対象になる。
別のディレクトリーを指定したいときは、sourceSetsのmain/protoを定義する。
〜
sourceSets {
main {
proto {
srcDir "${projectDir}/../grpc-example-server/src/main/proto"
}
}
}
〜
Java版gRPCサーバーのprotoファイルと同じものを使用する。
syntax = "proto3";
package example.grpc;
option java_multiple_files = true;
option java_package = "com.example.grpc.proto";
message Int64PairRequest {
int64 first_value = 1;
int64 second_value = 2;
}
message Int64PairResponse {
int64 first_value = 1;
int64 second_value = 2;
}
service ExampleService {
rpc SendInt64Pair(Int64PairRequest) returns (Int64PairResponse);
}
まず、生成されたserviceクラスを呼び出すクラスを実装する。
package com.example.grpc.client.service; import com.example.grpc.proto.ExampleServiceGrpc; import com.example.grpc.proto.ExampleServiceGrpc.ExampleServiceBlockingStub; import com.example.grpc.proto.Int64PairRequest; import com.example.grpc.proto.Int64PairResponse; import io.grpc.Channel; import io.grpc.StatusRuntimeException;
public class ExampleServiceClient {
private final ExampleServiceBlockingStub blockingStub;
public ExampleServiceClient(Channel channel) {
this.blockingStub = ExampleServiceGrpc.newBlockingStub(channel);
}
protoファイルをJava向けにビルドすると、XxxStub・XxxBlockingStub・XxxFutureStubという具合に、複数のStubクラスが生成される。
基本はXxxStubだが、レスポンスの取得方法がちょっと面倒なので、BlockingStubにメソッドが生成されているなら、それを使うのが楽。
(protoファイルのプロシージャーの引数がstreamだと、BlockingStubにはメソッドが生成されない)
public Int64PairResponse sendInt64Pair(long firstValue, long secondValue) {
var request = Int64PairRequest.newBuilder() //
.setFirstValue(firstValue) //
.setSecondValue(secondValue) //
.build();
try {
return blockingStub.sendInt64Pair(request);
} catch (StatusRuntimeException e) {
e.printStackTrace();
return null;
}
}
}
protoファイルではプロシージャー名はCamelCaseで書かれているが、Java向けに生成されたメソッド名はcamelCase(先頭が小文字)になる。
mainメソッドを実装する。
ここでgRPCのchannelを管理する。
package com.example.grpc.client; import com.example.grpc.client.service.ExampleServiceClient; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder;
public class GrpcExampleClient implements AutoCloseable {
public static void main(String[] args) {
int port = 50051;
var channel = ManagedChannelBuilder.forAddress("localhost", port) //
.usePlaintext() //
.build();
try (var main = new GrpcExampleClient(channel)) {
main.execute();
}
}
private final ManagedChannel channel;
public GrpcExampleClient(ManagedChannel channel) {
this.channel = channel;
}
public void execute() {
var client = new ExampleServiceClient(channel);
var response = client.sendInt64Pair(123, 456);
System.out.printf("response: %d, %d%n", response.getFirstValue(), response.getSecondValue());
}
@Override
public void close() {
channel.shutdown();
}
}
pluginsに「id 'application'」が指定してあるので、gradleのrunタスクで実行できる。
cd プロジェクト ./gradlew run