Protocol Buffer is a contract-defining ecosystem where you define a contract that your client and server understand and communicate within your contract’s boundary.

Read More: What is Protocol Buffer

Protocol Buffer can be used to define a gRPC server contract in Java and then any client can connect to the gRPC server using the defined contract

Protocol Buffer is defined using an Interface Definition Language agnostic to any Programming Language. You will create a .proto file. Then you will need a tool proto compiler to convert the .proto file to some other files that Java can understand

Prerequisite

  • Create Java Project

Project Structure

I created the project using Visual Studio Code and named the project user-management-system-grpc

  • Note: you can have different project structure based on the type of IDE and its version.
  • The Java code is present in the main folder
  • gradle configuration is written inside build.gradle file

Configure build.gradle for compiling Protobuf file and generating Java Code

You will be adding plugins and dependencies to your build.gradle file and then you will be able to compile and generate Java Files from the Protobuf(.proto) files.

Protobuf Gradle Plugin

  • GitHub Repo
  • This plugin helps in the orchestration process of getting the Protobuf Compiler (protoc) command line and uses it to generate Java source files out of your proto files.
  • It adds the generated Java source files to the input of the corresponding Java compilation unit (sourceSet in a Java project; variant in an Android project)

Inside the build.gradle file you need to add the Protobuf gradle plugin inside the plugins section

plugins {
    // Note there can be more things in you build.gradle file 
    id "com.google.protobuf" version "0.9.4"
}

Once the plugin is added then you need to define the protobuf task inside build.gradle file

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.21.1"
    }
    plugins {
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.62.2'
        }
    }
    generateProtoTasks {
        all()*.plugins {
            grpc {}
        }
    }
}

Let’s understand different section

protoc {
        artifact = "com.google.protobuf:protoc:3.21.1"
}

This tells Gradle how to find the Protobuf compiler. In our case, we are downloading it from the online repository. You can also download the compiler locally and then give the path information

plugins {
    grpc {
       artifact = 'io.grpc:protoc-gen-grpc-java:1.62.2'
    }
}

This tells Gradle which Java library will be used to generate the Java Classed from the .proto file

Add Java Dependencies to understand Generated Java Classes

When you generate the Java classes from .proto file then you need to add the libraries that help your project understand those files or classes.

We will be adding two dependencies

dependencies {
     // Note: There can be more dependencies based on your project

    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
    implementation 'javax.annotation:javax.annotation-api:1.3.2' 
    
    // dependencies for google-protobuf
    implementation group: 'io.grpc', name: 'grpc-protobuf', version: '1.62.2'
    implementation group: 'io.grpc', name: 'grpc-stub', version: '1.62.2'
}

Create Protobuf File

In Java Project, you need to create the proto folder inside the main folder. This folder is important because this is the place where the Protobuf Gradle Plugin searches for the .proto files

  • we created the proto folder inside the main folder
  • Inside the proto folder, you need to create a user_management.proto file that will contain all our Protobuf-related definitions.

Let’s put the below contents in the user_management.proto file

syntax = "proto3";
option java_multiple_files = true;
package com.cwrr.user_management;

message Error {
    string code = 1;
    string entity = 2;
    string message = 3;
}

message CreateUserRequest {
    string name = 1;
}

message CreateUserResponse {
    bool success = 1;
    Error error = 2;
    string user_id = 3;
}


service UserManagement {
    rpc CreateUser(CreateUserRequest) returns (CreateUserResponse); 
}

Service Definition

UserManagement service is defined which contains

  • CreateUser RPC
    • This accepts the CreateUserRequest and Returns CreateUserResponse message

Message

Three messages have been defined

  • CreateUserRequest
  • CreateUserResponse
  • Error

Options for Generating the Java Classes

  • syntax = “proto3”
    • This means that we are using proto3 syntax for writing our Protobuf file
  • option java_multiple_files = true
    • Multiple Java Files will be created when running the protoc compiler on the .proto file
  • package com.cwrr.user_management
    • This is the package name that will be used by other applications to use the proto-definitions

Building the Project

You need to run the below command to build your project

./gradlew clean build

This will generate the Java classes for your proto definitions.

Using Proto-Generated Classes in Your Project

You can directly use the classes present in the package com.cwrr.user_management

package user.management.system.grpc;

import com.cwrr.user_management.CreateUserRequest;
import com.cwrr.user_management.CreateUserRequestOrBuilder;

;

public class App {
    public String getGreeting() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        
        CreateUserRequest createUserRequest = CreateUserRequest.newBuilder()
        .setName("Raj Ranjan")
        .build();
    
    }

}

References

Related Post

One thought on “Protocol Buffer with Java”

Leave a Reply

Your email address will not be published. Required fields are marked *