We have a server
and client
application which shall talk to each other, both written in java and built with maven.
They interact via a gRPC interface.
We have different dependency situations on server
and client
:
server client | | --> lib-a --> *.protobuf | | | --> *.protobuf --> lib-b | | | --> *.protobuf --> *.protobuf
The server
includes libraries lib-a
and lib-b
which in turn need a subset of the messages that are defined in *.protobuf
. The server also needs some the stuff from *.protobuf
for himself.
The client
needs raw the *.protobuf
-files (not just generated java sources) to generate some more code from it (for use with mutiny).
We have the raw *.protobuf
sources are in a separate repository and now we need to distribute them somehow. The other dependencies are all managed by maven (server->lib-a, server->lib-b
)
We have some options how to provide this dependency.
- Generate classfiles from
*.protobuf
and distribute them as maven artifacts - Include the repository that contains
*.protobuf
as a git-submodule
but with each variant we face some problems:
problems with 1): the client
needs access to the raw *.protobuf
file to generate some more stuff from it (mutiny). Is there a way to distribute the raw file via maven as well? I also heared that it may be a bad practice to distribute generated code as maven artifacts(?)
problems with 2): we have a git-submodule in lib-a
, that would generate all *.class
files from *.protobuf
and include these generated sources in it’s published artifact. The same thing happens in lib-b
. If both libraries are released independently, it may happen that they include different versions of the generated sources. This may lead to issues when the server
includes both. In contrast to the maven-managed dependency, this is not explicit an there will be no warnings in the compile-process. Moreover, we would like to exclude SNAPSHOT
dependencies in our releases (which we currently enforce with maven-enforcer-plugin
). Is there some best-practice to achieve the same with git-submodules (my current best idea is to restrict allowed branch names for submodules in CI pipeline …)
I would really appreciate some advice here 🙂
Currently, I am also doing my own reading for:
- distributing the raw
*.protobuf
files via maven (see: Importing protocol buffer definitions between Maven projects) - providing the client-generated code as an artifact as well
Advertisement
Answer
The Maven and Gradle protobuf plugins include the .proto
files in the same library .jar
as the compiled generated files (.class
). This allows depending on a single jar and it providing the assets for protoc and javac.
I suggest making Maven libraries for your .protos and the related generated code. Treat it as a normal Java library.