Tuesday, October 26, 2021

ProtocolBuffer and its uses in JAVA

 There are many ways to send to and fro data between the application. The most command is using JSON and XML. But they had their own cost of implementation. Then come the concept of using schema base data transfer supported by JSON and AVRO. But finally google introduce ProtocolBuffer concept in which they transfer the data in a Schema base binary form ate. It has the following advantages.

Advantages:-[BSBSBS – binary, space, bandwidth, secure, backward compatibility, schema.]
1- It send the data in binary format.
2- As binary it is small in size
3- due to binary it is secure in nature.
4- Due to small is size its consume less bandwidth.
5- Support backward compatibility.
6- Support schema base data formate.
7- Provide support large number of language to create DTO object.

For more information, please refer to the below link:-

https://developers.google.com/protocol-buffers

But it also have disadvantage that as it is binary format it is not user readable.

In this blog we will try to understand how we can create a simple proto file and generate java DTO object from it.

Step 1- Download the protoc from below location we are using protoc with version 3.19.0 and set the path to C:\protoc-3.19.0-win64\bin

https://developers.google.com/protocol-buffers/docs/downloads

Check we are able to access protoc

Step 2- Lets create a simple .proto files as shown below we will call it as tutorial.proto we had taken it from google documentations.

https://developers.google.com/protocol-buffers/docs/cpptutorial

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1- tutorial.proto
 
    syntax = "proto2";
 
    package tutorial;
 
    option java_multiple_files = true;
    option java_package = "com.example.tutorial.protos";
    option java_outer_classname = "AddressBookProtos";
 
    message Person {
      optional string name = 1;
      optional int32 id = 2;
      optional string email = 3;
 
      enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
      }
 
      message PhoneNumber {
        optional string number = 1;
        optional PhoneType type = 2 [default = HOME];
      }
 
      repeated PhoneNumber phones = 4;
    }
 
    message AddressBook {
      repeated Person people = 1;
    }

Step 3- Now lets create a simple maven project as shown below.

Step 4- Add the following dependencies in our pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.19.0</version>
        </dependency>    
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.github.os72</groupId>
                <artifactId>protoc-jar-maven-plugin</artifactId>
                <version>3.11.4</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <protocVersion>3.19.0</protocVersion>
                            <inputDirectories>
                                <include>src/main/protobuf</include>
                            </inputDirectories>
                            <outputDirectory>src/main/generated</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    

our complete pom.xml would be like this.

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>siddhuproto</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.19.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.github.os72</groupId>
                <artifactId>protoc-jar-maven-plugin</artifactId>
                <version>3.11.4</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <protocVersion>3.19.0</protocVersion>
                            <inputDirectories>
                                <include>src/main/protobuf</include>
                            </inputDirectories>
                            <outputDirectory>src/main/generated</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Step 5- Create a folder protobuc and keep our tutorial.proto in it.

Now lets execute our .proto file with the below given command and generate JAVA DTO object.

1
protoc -I=C:/STS-Workspace/siddhuproto/src/main/protobuf --java_out=C:/STS-Workspace/siddhuproto/src/main/java C:/STS-Workspace/siddhuproto/src/main/protobuf/tutorial.proto

You will be able to see the java class is generated in the folder C:/STS-Workspace/siddhuproto/src/main/java given in –java_out parameter.

Note:- You will see some error in generated code.remove them by commenting this line in your java code
@java.lang.Override

now lets create mail JAVA files to test if the generated java files is working

Now write following code in it.

SiddhuTestProto.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package siddhuproto;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.example.tutorial.protos.AddressBook;
import com.example.tutorial.protos.Person;
import com.example.tutorial.protos.Person.PhoneNumber;
import com.example.tutorial.protos.Person.PhoneType;
 
 
public class SiddhuTestProto {
 
    public static void main(String[] args) {
 
        System.out.println("Hello world!");
 
 
        //For Tutorial proto
 
        //C:\Users\Siddhartha>protoc -I=C:/STS-Workspace/siddhuproto/src/main/protobuf --java_out=C:/STS-Workspace/siddhuproto/src/main/java C:/STS-Workspace/siddhuproto/src/main/protobuf/tutorial.proto
        Person.Builder builder = Person.newBuilder();
        builder.setName("siddhu");
        builder.setId(126);
        builder.setEmail("shdhumale@gmail.com");
 
        System.out.println("builder.toString():-"+builder.toString());
 
        PhoneNumber.Builder PhoneNumberBuilder = PhoneNumber.newBuilder();
        PhoneNumberBuilder.setNumber("1111111");
        PhoneNumberBuilder.setType(PhoneType.HOME);
        //builder.setPhones(0, PhoneNumberBuilder);
 
 
        PhoneNumber.Builder PhoneNumberBuilder1 = PhoneNumber.newBuilder();
        PhoneNumberBuilder1.setNumber("222222222");
        PhoneNumberBuilder1.setType(PhoneType.MOBILE);
        //builder.setPhones(1, PhoneNumberBuilder1);
 
 
        builder.addPhones(PhoneNumberBuilder).addPhones(PhoneNumberBuilder1);
 
 
        System.out.println("builder after adding PhoneNumberBuilder1.toString():-"+builder.toString());
 
 
        AddressBook.Builder AddressBookBuilder = AddressBook.newBuilder();
        //AddressBookBuilder.setPeople(1, builder);
        AddressBookBuilder.addPeople(builder);
 
 
 
        System.out.println("AddressBookBuilder.toString():-"+AddressBookBuilder.toString());
 
        AddressBook messageAddressBookBuilder = AddressBookBuilder.build();
 
        try {
            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Writing to the file<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ");
            FileOutputStream outputStream = new FileOutputStream("AddressBook_message.bin");
            messageAddressBookBuilder.writeTo(outputStream);
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
    }
}

you will be able to see the our code will serialize store the file and again read the data from the files as shown belwo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Our Output is:-
 
Hello world!
builder.toString():-name: "siddhu"
id: 126
email: "shdhumale@gmail.com"
 
builder after adding PhoneNumberBuilder1.toString():-name: "siddhu"
id: 126
email: "shdhumale@gmail.com"
phones {
  number: "1111111"
  type: HOME
}
phones {
  number: "222222222"
  type: MOBILE
}
 
AddressBookBuilder.toString():-people {
  name: "siddhu"
  id: 126
  email: "shdhumale@gmail.com"
  phones {
    number: "1111111"
    type: HOME
  }
  phones {
    number: "222222222"
    type: MOBILE
  }
}
 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Writing to the file<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

You will also see the file AddressBook_message.bin created and its size is too smaller than JASON or XML serialized files.

Download :-

https://github.com/shdhumale/siddhuproto.git


Note:-You can also create the java file for the given proto files by running project with "clean build" in maven. As we have protoc-jar-maven-plugin in our pom.xml and our protoc in class path it will create java files at the desired location. By creating java file by this we dont even need to remove this   @java.lang.Override and it contains another line i.e. @SuppressWarnings({"unused"})

No comments: