askaquestion
askaquestion

Reputation: 71

How GRPC .proto file works inside java jar file

I am new to GRPC and writing a sample java function using GRPC, I am using protobuf-maven-plugin to generate java files from my .proto file. Everything works fine on my local development. When I create the executable jar file I noticed at root dir of the jar there exists my .proto file

├───GRpc.proto
├───com
└───META-INF

I wonder do we need this .proto file inside the executable jar? If yes what is it's functionality when running the jar. Thanks.

Upvotes: 0

Views: 1301

Answers (2)

Eric Anderson
Eric Anderson

Reputation: 26464

The .protos are included in .jar to allow using protobuf dependencies as easily as java dependencies. Both protobuf-maven-plugin and protobuf-gradle-plugin support searching dependencies for protos.

The idea is to have generated code for protos published to Maven Central. Those artifacts contain enough for both java and protobuf.

The simplest example is protobuf-java itself. Protobuf has "well known protos" like google.protobuf.Any and google.protobuf.Empty. Let's say you make a proto that uses one:

syntax = "proto3";

package mypackage;

import "google/protobuf/any.proto";

message MyMethod {
  google.protobuf.Any anyField = 1;
}

To generate code for that .proto, the any.proto file is needed. But to compile generated java code the com.google.protobuf.Any class is needed. Somehow you need two dependencies.

Placing the .proto in the .jar allows only adding a single dependency to satisfy both the protobuf dependency and the java dependency:

    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
      <version>3.21.1</version>
    </dependency>

Protobuf-java is not a special case. For example, https://github.com/googleapis/googleapis publishes generated java code for its protos in artifacts like com.google.api.grpc:proto-google-common-protos. That dependency includes the .protos as well so a single dependency satisfies Protobuf and Java.

As you make your own protos and publish generated Java code, the protos are included to allow others to create their own protos that depend on yours.

Upvotes: 2

Andrew Cheong
Andrew Cheong

Reputation: 30293

It doesn't need to be there for the running of your program. However, it's probably there because it's just an important-enough thing to share in the gRPC ecosystem.

The most direct use of the .proto is so that others can generate a client that talks to your .proto-generated service, which you probably already know.

In case you or others don't know though: The whole point of gRPC is that once someone defines a .proto to describe their service, although the service needs some extra coding (i.e. you have to supply the logic), a fully working client can be generated with no extra coding. So to be more specific in an example, you (1) generate a server using protobuf-maven-plugin, (2) you have to @Override the stubs with your logic and return data via StreamObserver, and (3) you eventually build and deploy your server somewhere. Meanwhile another person somewhere can apply gRPC Python tools on your .proto to generate a Python client, all ready to speak to your service.

But okay, what use could it have in a .jar? Again, it's just a very important document—the "DNA" or contract of the service. Imagine in the future there are plug-ins and tools that "enhance" a proto-generated Java service in different ways. Those plug-ins and tools would be far easier to write if they can assume they'll be given the .proto file, rather than reverse engineering Java bytecode to figure out what original contract you started from.

tl;dr - A large part of gRPC is about interoperability, so it makes sense to share the very file that encodes that interoperability, for applications that are both known and unknown (in the future).

Upvotes: 2

Related Questions