Protocol Buffer compiler plugin that generates Java gRPC service interfaces, client stubs, and server implementations from .proto files
npx @tessl/cli install tessl/maven-io-grpc--protoc-gen-grpc-java@1.73.0protoc-gen-grpc-java is a Protocol Buffer compiler plugin that generates Java language bindings for gRPC services defined in .proto files. It integrates with the Protocol Buffer compiler (protoc) to automatically generate Java client stubs, server implementations, and service interfaces from protobuf service definitions.
mvn dependency:get -Dartifact=io.grpc:protoc-gen-grpc-java:1.73.0:exe:${os.detected.classifier}The plugin is invoked through protoc and generates Java gRPC service stubs from .proto service definitions:
# Basic gRPC Java code generation
protoc --plugin=protoc-gen-grpc-java=/path/to/protoc-gen-grpc-java \
--grpc-java_out="./generated" \
--proto_path="./protos" \
service.protoWith Maven (using protobuf-maven-plugin):
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.24.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.73.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
</plugin># Generate Java gRPC service stubs from a proto file
mkdir -p generated/java
protoc --plugin=protoc-gen-grpc-java=./protoc-gen-grpc-java \
--grpc-java_out="./generated/java" \
--proto_path="./protos" \
user_service.proto
# Generate with lite protobuf runtime
protoc --plugin=protoc-gen-grpc-java=./protoc-gen-grpc-java \
--grpc-java_out=lite:"./generated/java" \
--proto_path="./protos" \
user_service.proto
# Generate without version annotations
protoc --plugin=protoc-gen-grpc-java=./protoc-gen-grpc-java \
--grpc-java_out=noversion:"./generated/java" \
--proto_path="./protos" \
user_service.protoGiven this proto file:
syntax = "proto3";
package com.example;
option java_package = "com.example.user";
service UserService {
rpc GetUser(GetUserRequest) returns (UserResponse);
rpc ListUsers(ListUsersRequest) returns (stream UserResponse);
}The plugin generates: com/example/user/UserServiceGrpc.java with client stubs, server base class, and method descriptors.
The plugin implements the protoc plugin protocol and accepts configuration through protoc command-line options.
# Plugin invocation through protoc
protoc --plugin=protoc-gen-grpc-java=<path-to-executable> \
--grpc-java_out=[OPTIONS:]<output-directory> \
[--proto_path=<proto-directories>] \
<proto-files>
# Supported options (comma-separated):
# lite - Generate lite protobuf bindings
# noversion - Omit version information in generated code
# @generated=omit - Omit @Generated annotations
# @generated=javax - Use javax.annotation.Generated (default)Generates complete Java gRPC service implementations including stubs, method descriptors, and server base classes.
// Core code generation function
void GenerateService(
const google::protobuf::ServiceDescriptor* service,
google::protobuf::io::ZeroCopyOutputStream* output,
ProtoFlavor flavor,
bool disable_version,
GeneratedAnnotation generated_annotation
);Parameters:
service: Protobuf service descriptor containing RPC method definitionsoutput: Output stream for generated Java codeflavor: Generation mode (NORMAL or LITE protobuf runtime)disable_version: Whether to omit version information in generated codegenerated_annotation: Annotation generation strategy (OMIT or JAVAX)Determines Java package names and class names for generated service stubs.
// Get Java package name for generated service classes
std::string ServiceJavaPackage(
const google::protobuf::FileDescriptor* file
);
// Get outer class name for generated service code
std::string ServiceClassName(
const google::protobuf::ServiceDescriptor* service
);ServiceJavaPackage returns the Java package name based on:
java_package option in the .proto file, orServiceClassName returns the service name with "Grpc" suffix (e.g., "UserService" → "UserServiceGrpc").
Implements the protobuf compiler plugin interface for seamless integration with protoc.
class JavaGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
public:
// Get supported protobuf features
uint64_t GetSupportedFeatures() const override;
// Get minimum supported protobuf edition
google::protobuf::Edition GetMinimumEdition() const override;
// Get maximum supported protobuf edition
google::protobuf::Edition GetMaximumEdition() const override;
// Main code generation entry point
bool Generate(
const google::protobuf::FileDescriptor* file,
const std::string& parameter,
google::protobuf::compiler::GeneratorContext* context,
std::string* error
) const override;
};Supported Features:
FEATURE_PROTO3_OPTIONAL: Proto3 optional field supportFEATURE_SUPPORTS_EDITIONS: Protobuf editions supportSupported Editions: EDITION_PROTO2 through EDITION_2023
The plugin generates Java classes following gRPC Java conventions:
For each protobuf service, generates a final class named {ServiceName}Grpc:
// Generated service class structure
@javax.annotation.Generated(
value = "by gRPC proto compiler (version 1.73.0)",
comments = "Source: user_service.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class UserServiceGrpc {
// Service name constant
public static final String SERVICE_NAME = "com.example.UserService";
// Method descriptor getters
public static MethodDescriptor<GetUserRequest, UserResponse> getGetUserMethod();
public static MethodDescriptor<ListUsersRequest, UserResponse> getListUsersMethod();
// Factory methods for creating client stubs
public static UserServiceStub newStub(Channel channel);
public static UserServiceBlockingStub newBlockingStub(Channel channel);
public static UserServiceFutureStub newFutureStub(Channel channel);
// Service binding for server implementations
public static ServerServiceDefinition bindService(UserServiceImplBase serviceImpl);
// Client stub classes
public static final class UserServiceStub
extends AbstractAsyncStub<UserServiceStub> {
// Async streaming client methods
}
public static final class UserServiceBlockingV2Stub
extends AbstractBlockingStub<UserServiceBlockingV2Stub> {
// Blocking stub with V2 interface
}
public static final class UserServiceBlockingStub
extends AbstractBlockingStub<UserServiceBlockingStub> {
// Synchronous blocking client methods
}
public static final class UserServiceFutureStub
extends AbstractFutureStub<UserServiceFutureStub> {
// Asynchronous future-based client methods
}
// Server implementation base class
public static abstract class UserServiceImplBase
implements BindableService, AsyncService {
// Abstract methods for server implementation
@Override public final ServerServiceDefinition bindService() {
return UserServiceGrpc.bindService(this);
}
}
}Each RPC method gets a corresponding method descriptor with proper marshalling:
// Generated method descriptor pattern
private static volatile MethodDescriptor<RequestType, ResponseType> getMethodName;
@io.grpc.stub.annotations.RpcMethod(
fullMethodName = SERVICE_NAME + "/MethodName",
requestType = RequestType.class,
responseType = ResponseType.class,
methodType = MethodDescriptor.MethodType.UNARY // or SERVER_STREAMING, etc.
)
public static MethodDescriptor<RequestType, ResponseType> getMethodName() {
MethodDescriptor<RequestType, ResponseType> getMethodName;
if ((getMethodName = ServiceGrpc.getMethodName) == null) {
synchronized (ServiceGrpc.class) {
if ((getMethodName = ServiceGrpc.getMethodName) == null) {
ServiceGrpc.getMethodName = getMethodName =
MethodDescriptor.<RequestType, ResponseType>newBuilder()
.setType(MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(SERVICE_NAME, "MethodName"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(ProtoUtils.marshaller(
RequestType.getDefaultInstance()))
.setResponseMarshaller(ProtoUtils.marshaller(
ResponseType.getDefaultInstance()))
.setSchemaDescriptor(new ServiceMethodDescriptorSupplier("MethodName"))
.build();
}
}
}
return getMethodName;
}The plugin supports all gRPC method types:
rpc GetUser(GetUserRequest) returns (UserResponse);Generates: Synchronous request-response methods
rpc ListUsers(ListUsersRequest) returns (stream UserResponse);Generates: Methods returning Iterator<UserResponse> (blocking) or StreamObserver<UserResponse> (async)
rpc CreateUsers(stream CreateUserRequest) returns (CreateUsersResponse);Generates: Methods accepting StreamObserver<CreateUserRequest> and returning response observer
rpc ChatUsers(stream ChatMessage) returns (stream ChatMessage);Generates: Methods with bidirectional StreamObserver<ChatMessage>
// build.gradle configuration
plugins {
id 'java'
id 'com.google.protobuf' version '0.9.4'
}
def grpcVersion = '1.73.0'
def protobufVersion = '3.24.0'
dependencies {
implementation "io.grpc:grpc-stub:${grpcVersion}"
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "com.google.protobuf:protobuf-java:${protobufVersion}"
// Required for annotation processing
compileOnly "javax.annotation:javax.annotation-api:1.3.2"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${protobufVersion}"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}<!-- pom.xml configuration -->
<properties>
<grpc.version>1.73.0</grpc.version>
<protobuf.version>3.24.0</protobuf.version>
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>// Code generation configuration enums
enum ProtoFlavor {
NORMAL, // Standard protobuf runtime
LITE // Lite protobuf runtime (smaller footprint)
};
enum GeneratedAnnotation {
OMIT, // Omit @Generated annotations
JAVAX // Use javax.annotation.Generated annotations
};// gRPC method types supported in generated code
enum MethodType {
UNARY, // Single request, single response
CLIENT_STREAMING, // Stream of requests, single response
SERVER_STREAMING, // Single request, stream of responses
BIDI_STREAMING // Stream of requests, stream of responses
}
// Key interfaces used in generated code
interface BindableService {
ServerServiceDefinition bindService();
}
interface AsyncService {
// Marker interface for async service implementations
}
// Abstract stub base classes
abstract class AbstractAsyncStub<T extends AbstractAsyncStub<T>> {
protected AbstractAsyncStub(Channel channel, CallOptions callOptions);
protected abstract T build(Channel channel, CallOptions callOptions);
}
abstract class AbstractBlockingStub<T extends AbstractBlockingStub<T>> {
protected AbstractBlockingStub(Channel channel, CallOptions callOptions);
protected abstract T build(Channel channel, CallOptions callOptions);
}
abstract class AbstractFutureStub<T extends AbstractFutureStub<T>> {
protected AbstractFutureStub(Channel channel, CallOptions callOptions);
protected abstract T build(Channel channel, CallOptions callOptions);
}
// Server service definition for registration
class ServerServiceDefinition {
// Service definition for gRPC server registration
}
// Utility classes used in generated code
class ClientCalls {
public static <ReqT, RespT> void asyncUnaryCall(
ClientCall<ReqT, RespT> call, ReqT request,
StreamObserver<RespT> responseObserver);
public static <ReqT, RespT> RespT blockingUnaryCall(
Channel channel, MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions, ReqT request);
public static <ReqT, RespT> ListenableFuture<RespT> futureUnaryCall(
ClientCall<ReqT, RespT> call, ReqT request);
}
class ProtoUtils {
public static <T extends Message> Marshaller<T> marshaller(T defaultInstance);
}The plugin reports errors through the protoc plugin interface:
Errors are reported via protoc's standard error handling mechanism and will cause the compilation to fail with descriptive error messages.
The plugin is distributed as platform-specific native executables:
Each platform executable is available as a separate Maven classifier (e.g., linux-x86_64, osx-x86_64, windows-x86_64).