Reputation: 71
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
Reputation: 26464
The .proto
s 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 .proto
s 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
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