devxlogo

Implement Java Object Management Using a Protocol Buffer

Implement Java Object Management Using a Protocol Buffer

A protocol buffer is the simplest and most efficient way to manage structured data, largely because of its built-in support for serializing messages. The types of messages a protocol buffer can manage include structured data forms and composite messages. The message is stored in the .proto extension file. Normally, developers call this type of message as a proto message.

For Java developers, Google provides a protocol buffer compiler for Java. Developers can use this compiler to convert a .proto message to a Java-based source file of the message, which can help speed up storage and retrieval of data.

In this article, we will explain how to implement Java object management using a protocol buffer and the Google protocol buffer compiler.

Anatomy of a Message in Java

A message is a collection of different fields/attributes stored in a single name, where a field is a combination of different scalar types, composite types and enumerations.

The types of messages a protocol buffer can manage include structured data forms and composite messages. The message is stored in the .proto extension file. Normally, developers call this type of message as a proto message.

The following is the syntax for a message type:

message  {

= }

A message has the following field rules:

  1. Required: This field is mandated while saving the file and validated as part of well-formed message.
  2. Optional: A message can have zero or more fields, and the value of the field may be optional.
  3. Repeated: This field can be repeated any number of times.

You can use the following data types in field declarations:

  1. All Java primitive data types (e.g. int, long, float, double, Boolean)
  2. String and ByteString

To name fields, you simply follow the Java variable naming approach.

Each field in the message is tagged with a tag value. The tag value is used to identify the field in the message binary format, and its size range is from 1 to 536,870,911. This value cannot change once the message is in use. A developer can reserve the tag value for frequent-usage fields. The value range of 1 to 15 is for frequent-usage fields and it takes one byte to encode tag value. The range 16 to 2047 takes two bytes.

The following is an example message type:

message employee {required int empno=1;required String name=2;optional String sex=3;}message emp_record {repeated employee emp=1; //employee message repeated any number of times.}

A message also supports the following:

  1. Using // to add comments in the message
  2. Declaring one or more message in the same .proto file
  3. Declaring nested messages (i.e. a message within a message).

A developer can also set the following message attributes using proto:

  1. The package for a message
  2. The Java class name for the message
  3. The default value for the message field

Here’s a sample message that shows all the above support:

Option java_package ="com.emp";Option java_outer_classname= "EmployeeProto";message emp{       required int empno=1; //Employee id –comments       optional String name=2;       optional String sex=3; [default="M"];      //Message Enum declaration       enum phonetype {HOME=1;MOBILE=2;OFFICE=3;       }       //Nested Message –Composite type message       message contact{optional string number=1;optional phonetype type=2; [default=MOBILE]       }      repeated  contact empcontact=4; }

The Google Protocol Buffer Compiler for Java

Developers can download Google’s complier from the protobuf download page. As previously stated, this compiler converts a .proto message to a Java-based source file of the message. Here is the command for converting a message to a Java source file.

Protoc --proto_path=  --java_out=  

Using this Java output, a developer can build a message (which is used for storing and retrieving a message in the file). Messages are stored as objects in the file, which helps speed up storage and retrieval of data. While storing the object in the output file, the stored object also gets serialized. If any change occurs in the message, the developer must rebuild the proto message.

The proto compiler reads the message, creates the package folder and sets the outer class name for the output Java file of the message in the package folder. Developers should use the JAR files below for object management, which is included with the proto compiler download.

  1. protobuf-java-.jar
  2. protobuf-format-java-1.1.jar

Java Object Management Using Proto Messages

Developers should import the proto compiler’s Java output into their Java files. The proto compiler’s Java output is called proto Java. This proto Java has an object builder class, which is used to build the message object as well as for storing and retrieving a message in the output file.

As an example, the following code snippet is an employee proto message.

option java_package = "com.emp";option java_outer_classname = "EmpProtos";message Employee {  required string name = 1;  required int32 id = 2; // Unique ID number for this employee  optional string email = 3;}message Emprecord {  repeated Employee emp = 1;}

The following code snippet uses a proto Java file for object management, and it writes the employee object into the output file as a serialized form.

package com.emp;import java.io.*;import com.emp.EmpProtos.*; //importing the Java proto which is created by proto compiler.  //writing the employee record into the output file  public static void addEmployee(int id ,String name,String email,  FileOutputStream fout)  throws Exception {Emprecord.Builder recBuilder = Emprecord.newBuilder();Employee.Builder empBuilder = Employee.newBuilder();empBuilder.setName(name);empBuilder.setId(id);empBuilder.setEmail(email);recBuilder.addEmp(empBuilder.build());recBuilder.build().writeTo(fout);  }

The following code snippet is for reading the employee record in the input file.

//Reading the employee record from the file  public static void readEmprecord(FileInputStream fin) throws Exception {Emprecord empList =Emprecord.parseFrom(fin);System.out.println("==Employee List ==");if(empList != null){for (Employee emp: empList.getEmpList()) {   System.out.println(emp.getId()+" "+emp.getName()+" "+getEmail());}}  }

Use the above two code snippets as examples that you can apply to your own object management implementation using proto Java files.

devx-admin

Share the Post: