Skip to content

Protocol Buffers (Protobuf)

Messaging & StreamingSerialization / MessagingJava

What it is

Protocol Buffers (Protobuf) is a language-neutral, platform-neutral, and extensible mechanism for serializing structured data. It is used to efficiently encode data for communication between services, storage, or configuration in Java applications.

Protobuf allows you to define structured data in `.proto` files, generate Java classes, and serialize/deserialize data efficiently. It supports messages, enums, nested structures, and repeated fields.

Installation

Add dependency in pom.xml: <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.24.3</version> </dependency>

Getting started

The smallest useful thing you can do with it, and what each part means.

Defining a message in a .proto file
syntax = "proto3";

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
}
Defines a simple `Person` message with `name`, `id`, and `email` fields.
Generating Java classes
# Using protoc compiler
protoc --java_out=src/main/java person.proto
Generates Java classes from the .proto definition for use in your application.

Advanced usage

Where the library earns its place over a simpler alternative.

Serializing a message
Person person = Person.newBuilder()
    .setName("Alice")
    .setId(1)
    .setEmail("alice@example.com")
    .build();

byte[] data = person.toByteArray();
Builds a Protobuf message and serializes it to a byte array for storage or transmission.
Deserializing a message
Person parsedPerson = Person.parseFrom(data);
System.out.println(parsedPerson.getName());
Parses a byte array back into a Protobuf message instance.
Using nested messages and enums
message AddressBook {
  repeated Person people = 1;
}

AddressBook book = AddressBook.newBuilder()
    .addPeople(person)
    .build();
Shows how to define repeated (list) fields and nested messages in Protobuf.
Working with optional and default values
Person person = Person.newBuilder()
    .setName("Bob")
    .build();
System.out.println(person.getEmail()); // empty string as default
Optional fields take default values if not explicitly set.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

InvalidProtocolBufferException
Occurs when parsing corrupted or incompatible byte arrays. Ensure the data matches the message schema.
Missing required fields
Ensure all required fields are set before serialization (for proto2 syntax) or rely on default values (proto3).

Best practices

  • Use `.proto` version 3 syntax for simplicity and modern features.
  • Leverage repeated fields instead of lists for efficient storage.
  • Keep backward and forward compatibility by assigning unique field numbers.
  • Avoid removing fields; deprecate them instead to maintain compatibility.
  • Use Protobuf for inter-service communication, storage, or network efficiency.

Background

Why it exists, and what it was reacting to.

Protobuf was developed by Google to provide a faster and smaller alternative to XML and JSON for serializing structured data. It supports backward and forward compatibility, strong typing, and works across multiple languages. Protobuf is widely used in RPC systems, microservices, data storage, and messaging applications.