Programmatic ProtoStream Marshalling

What You Will Learn

How to define a Protobuf schema in Java code using the Schema.Builder API, implement a custom MessageMarshaller, and register both with the Hot Rod client — all without using @Proto annotations.

Prerequisites

  • Java 17+

  • An Infinispan Server running on localhost:11222 (or Docker/Podman available for Testcontainers)

Start an Infinispan Server with Docker or Podman:

docker run -it --rm -p 11222:11222 -e USER=admin -e PASS=password quay.io/infinispan/server:latest
Tip
You can replace docker with podman in the command above if you use Podman.
Tip
If no server is running, the tutorial code automatically starts an Infinispan Server using Testcontainers.

Step 1: Define the Data Model and Schema

Create a simple Java record for the entity:

public record Magazine(String name, YearMonth publicationDate, List<String> stories) {
}

Use the Schema.Builder API to define the schema in code:

    static public Schema magazineSchema() {
        return new Schema.Builder("magazine.proto")
                .packageName("magazine_sample")
                .addMessage("Magazine")
                .addField(Type.Scalar.STRING, "name", 1)
                .addField(Type.Scalar.INT32, "publicationYear", 2)
                .addField(Type.Scalar.INT32, "publicationMonth", 3)
                .addRepeatedField(Type.Scalar.STRING, "stories", 4)
                .build();
    }

Step 2: Implement and Register the Marshaller

Create a MessageMarshaller to convert between your Java type and Protobuf, then register the schema and marshaller with the ProtoStreamMarshaller and upload the schema to the server:

      ProtoStreamMarshaller marshaller = new ProtoStreamMarshaller();
      SerializationContext serializationContext = marshaller.getSerializationContext();
      FileDescriptorSource fds = FileDescriptorSource.fromString(schema.getName(), schema.toString());
      serializationContext.registerProtoFiles(fds);
      serializationContext.registerMarshaller(new MagazineMarshaller());
      builder.marshaller(marshaller);
      builder.remoteCache(TUTORIAL_CACHE_NAME);

      // Connect to the server
      client = TutorialsConnectorHelper.connect(builder);

      // Create and add the Protobuf schema in the server
      client.administration().schemas().createOrUpdate(schema);

The MagazineMarshaller implements MessageMarshaller<Magazine> with readFrom and writeTo methods that map record fields to Protobuf fields.

Step 3: Run the Tutorial

mvn package exec:java

You should see a magazine entry printed from the cache, confirming the programmatic schema and marshaller work correctly.

What’s Next