Protobuf for lazy Java coders.

Sometimes you are just plain lazy and would rather have Maven create the Java files out of .proto. The alternative would have been to download the protoc, fire up the terminal and issue one simple command. Not a big deal at all. But as I said sometimes you are just plain lazy.

So how do you go about it. Follow the steps given below.

Think up a super critical message that you want to send across over the wire.
If you dont know how to write a .proto file, perhaps one of the links below would help.
https://developers.google.com/protocol-buffers/docs/proto
https://developers.google.com/protocol-buffers/docs/proto3
The one below is the super critical hello world that I want to send across.

#1
syntax = "proto2";
// This is the package where the java source code will be placed.
option java_package = "le.arn";
// This is the name of the class.
// If not provided, it will be created as <message name>OuterClass.
option java_outer_classname = "GreetingProtos";
message Greeting {
required string greeting = 1;
}

Create a vanilla maven project. 
Say thanks to open source and add protoc-jar-maven-plugin to the project. 

#2
<!-- protobuf. (de)serialize proto buffers using java api. -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.2.0</version>
</dependency>

This would create the java files.
However they will complain that the google libraries are not around. 
So you will have to add the protobuf libraries. 

#3
<!-- compile proto file into java files. -->
<plugin>
<groupId>com.github.os72</groupId>
<artifactId>protoc-jar-maven-plugin</artifactId>
<version>3.2.0.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<!-- <includeDirectories> <include>src/main/protobuf</include> </includeDirectories> -->
<inputDirectories>
<include>src/main/protobuf</include>
</inputDirectories>
<!-- Create java files. And put them in the src/main/java directory. -->
<outputTargets>
<outputTarget>
<type>java</type>
<outputDirectory>src/main/java</outputDirectory>
</outputTarget>
</outputTargets>
</configuration>
</execution>
</executions>
</plugin>

The proof of the pudding is in eating it. 
Let's write a test to serialize and deserialize the super critical message. 

#4
// 1 : Create a Greeting object using the Protobuf builder.
Builder greetingBuilder = GreetingProtos.Greeting.newBuilder();
greetingBuilder.setGreeting(HELLO_WORLD);
Greeting greeting = greetingBuilder.build();
try {
// 2 : Write the message into a file. Serialize the object.
FileOutputStream output = new FileOutputStream(SER_FILE);
greeting.writeTo(output);
output.close();
// 3 : Deserialize the object from the file.
Greeting greetingFromFile = Greeting.parseFrom(new FileInputStream(
SER_FILE));
logger.debug("We read this from the file {}", greetingFromFile);
// 4 : All is well?
assertEquals(HELLO_WORLD, greetingFromFile.getGreeting());
} catch (IOException e) {
e.printStackTrace();
}
view raw UnitTest.java hosted with ❤ by GitHub

That's it. You have a Java project that does the basic steps i.e. serialization / deserialization using protobuf. Hope that is helpful. If you know a easier, quicker way please share as well. 

Either ways your comments will be appreciated. Please take a couple of minutes and write back. 

No comments:

Post a Comment