Skip to content
Advertisement

Transitive Dependencies on generated (gGRPC) code with java/maven

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.

  1. Generate classfiles from *.protobuf and distribute them as maven artifacts
  2. 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:

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.

Advertisement