gRPC integration for Protocol Buffers with utilities for serialization, marshalling, and metadata handling
npx @tessl/cli install tessl/maven-io-grpc--grpc-protobuf@1.73.0gRPC Protobuf provides seamless integration between gRPC and Protocol Buffers, enabling automatic serialization and deserialization of protobuf messages in gRPC applications. It offers utilities for creating marshallers, handling extension registries, converting between protobuf messages and gRPC metadata, and working with status protos.
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.73.0</version>
</dependency>implementation 'io.grpc:grpc-protobuf:1.73.0'import io.grpc.protobuf.ProtoUtils;
import io.grpc.protobuf.StatusProto;
import io.grpc.protobuf.ProtoServiceDescriptorSupplier;
import io.grpc.protobuf.ProtoMethodDescriptorSupplier;
import io.grpc.protobuf.ProtoFileDescriptorSupplier;
import io.grpc.MethodDescriptor.Marshaller;
import io.grpc.Metadata;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.Message;
import com.google.errorprone.annotations.CheckReturnValue;import io.grpc.protobuf.ProtoUtils;
import com.google.protobuf.Message;
import io.grpc.MethodDescriptor;
// Create a marshaller for a protobuf message type
MyProtoMessage defaultInstance = MyProtoMessage.getDefaultInstance();
MethodDescriptor.Marshaller<MyProtoMessage> marshaller = ProtoUtils.marshaller(defaultInstance);
// Create metadata key for protobuf messages
Metadata.Key<MyProtoMessage> metadataKey = ProtoUtils.keyForProto(defaultInstance);
// Set extension registry globally (if needed)
ExtensionRegistry registry = ExtensionRegistry.newInstance();
// register your extensions...
ProtoUtils.setExtensionRegistry(registry);Create marshallers for protobuf messages to enable automatic serialization/deserialization in gRPC method descriptors.
public static <T extends Message> Marshaller<T> marshaller(final T defaultInstance);
public static <T extends Message> Marshaller<T> marshallerWithRecursionLimit(T defaultInstance, int recursionLimit);Configure global extension registry for protobuf marshalling across all gRPC servers and clients.
public static void setExtensionRegistry(ExtensionRegistry registry);Convert protobuf messages to gRPC metadata keys and marshallers for header transmission.
public static <T extends Message> Metadata.Key<T> keyForProto(T instance);
public static <T extends Message> Metadata.BinaryMarshaller<T> metadataMarshaller(T instance);Convert between com.google.rpc.Status protos and gRPC Status/Exception types for rich error handling.
public static StatusRuntimeException toStatusRuntimeException(com.google.rpc.Status statusProto);
public static StatusRuntimeException toStatusRuntimeException(com.google.rpc.Status statusProto, Metadata metadata);
public static StatusException toStatusException(com.google.rpc.Status statusProto);
public static StatusException toStatusException(com.google.rpc.Status statusProto, Metadata metadata);
public static StatusException toStatusException(com.google.rpc.Status statusProto, Metadata metadata, Throwable cause);
public static com.google.rpc.Status fromThrowable(Throwable t); // @Nullable return
public static com.google.rpc.Status fromStatusAndTrailers(Status status, @Nullable Metadata trailers);Interfaces for providing access to protobuf descriptors in generated code.
public interface ProtoFileDescriptorSupplier {
FileDescriptor getFileDescriptor();
}
public interface ProtoServiceDescriptorSupplier extends ProtoFileDescriptorSupplier {
ServiceDescriptor getServiceDescriptor();
}
public interface ProtoMethodDescriptorSupplier extends ProtoServiceDescriptorSupplier {
@CheckReturnValue
MethodDescriptor getMethodDescriptor();
}import io.grpc.MethodDescriptor;
import io.grpc.protobuf.ProtoUtils;
// Assuming you have MyRequest and MyResponse protobuf message types
private static final MethodDescriptor<MyRequest, MyResponse> METHOD_DESCRIPTOR =
MethodDescriptor.<MyRequest, MyResponse>newBuilder()
.setType(MethodDescriptor.MethodType.UNARY)
.setFullMethodName("MyService/MyMethod")
.setRequestMarshaller(ProtoUtils.marshaller(MyRequest.getDefaultInstance()))
.setResponseMarshaller(ProtoUtils.marshaller(MyResponse.getDefaultInstance()))
.build();import io.grpc.Metadata;
import io.grpc.protobuf.ProtoUtils;
// Create metadata key for a protobuf message
Metadata.Key<MyProtoMessage> key = ProtoUtils.keyForProto(MyProtoMessage.getDefaultInstance());
// Create metadata and add protobuf message
Metadata metadata = new Metadata();
MyProtoMessage message = MyProtoMessage.newBuilder()
.setField("value")
.build();
metadata.put(key, message);import io.grpc.protobuf.StatusProto;
import com.google.rpc.Status;
import io.grpc.StatusRuntimeException;
// Convert RPC status proto to gRPC exception
Status statusProto = Status.newBuilder()
.setCode(5) // NOT_FOUND
.setMessage("Resource not found")
.build();
StatusRuntimeException exception = StatusProto.toStatusRuntimeException(statusProto);
// Extract status proto from exception
com.google.rpc.Status extractedStatus = StatusProto.fromThrowable(exception);import com.google.protobuf.ExtensionRegistry;
import io.grpc.protobuf.ProtoUtils;
// Set up extension registry for custom protobuf extensions
ExtensionRegistry registry = ExtensionRegistry.newInstance();
registry.add(MyExtensions.myCustomExtension);
ProtoUtils.setExtensionRegistry(registry);
// Now all marshallers will use this registry for parsing extensions
MethodDescriptor.Marshaller<MyMessage> marshaller =
ProtoUtils.marshaller(MyMessage.getDefaultInstance());// From io.grpc
class Metadata {
static class Key<T> {
String originalName();
}
static interface BinaryMarshaller<T> {}
}
// From io.grpc (different from com.google.protobuf.Descriptors.MethodDescriptor)
interface MethodDescriptor {
interface Marshaller<T> {
InputStream stream(T value);
T parse(InputStream stream);
}
}
class Status {
Code getCode();
String getDescription();
Status withDescription(String description);
Status withCause(Throwable cause);
StatusException asException(Metadata trailers);
StatusRuntimeException asRuntimeException(Metadata trailers);
}
class StatusException extends Exception {
Status getStatus();
Metadata getTrailers();
}
class StatusRuntimeException extends RuntimeException {
Status getStatus();
Metadata getTrailers();
}// From com.google.protobuf
interface Message {
Descriptors.Descriptor getDescriptorForType();
}
class ExtensionRegistry {
static ExtensionRegistry newInstance();
void add(GeneratedMessage.GeneratedExtension<?, ?> extension);
}
class Descriptors {
static class FileDescriptor {
String getFullName();
}
static class ServiceDescriptor {
String getFullName();
}
static class MethodDescriptor {
String getFullName();
}
}The StatusProto class provides experimental APIs for working with rich error information using com.google.rpc.Status protos. Common exceptions:
When using extension registries: