The source *.proto
files are automatically added to the list of project resources, so when the project is built, they included in the resulting jar artifact.
When building a dependent project, every dependency in the compile
(or test
) scope is also automatically scanned for *.proto
resources, and they are included on the include path for protobuf compiler. This also works for multi-module Maven reactor projects.
By convention, protobuf sources are expected to be inside src/main/proto
directory (although this is configurable).
The main requirement is that if a protobuf package is declared in the proto file, it must match its subdirectory under src/main/proto
. If there is no package declaration, the file must reside directly inside src/main/proto
and not in any subdirectory thereof. Otherwise protobuf compiler will have major problems resolving imports.
So if a test1.proto
file contains:
package it.project1;
...then the proto file should reside in src/main/proto/it/project1
. And another proto file (possibly in another Maven module or project) will then be able to import it:
import "it/project1/test1.proto";
When building a dependent project, where protobuf definitions import other definitions that are packaged into dependencies, it is important to make sure that the compiled classes are also available on the classpath (for example, imported through the same jar dependency).
In a typical scenario, simply declaring a Maven dependency is enough, as long as it's been generated by another-protobuf-maven-plugin
or follows the same packaging structure.
When generating Java code com.google.protobuf:protobuf-java
dependency must always be included and must be of the same version as protobuf compiler. That dependency has some core protobuf definitions bundled too.
Sample configuration that demonstrates both the usage of dependencies and the usage of additional protobuf compiler plugins:
<project> ... <properties> <protobufVersion>3.11.1</protobufVersion> <grpcVersion>1.7.0</grpcVersion> </properties> ... <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.6.1</version> </extension> </extensions> <plugins> <plugin> <groupId>dev.cookiecode</groupId> <artifactId>another-protobuf-maven-plugin</artifactId> <version>2.1.0</version> <configuration> <!-- Common configuration, used by all goals --> <protocArtifact> com.google.protobuf:protoc:${protobufVersion}:exe:${os.detected.classifier} </protocArtifact> </configuration> <executions> <execution> <id>protoc-java</id> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>protoc-grpc</id> <goals> <goal>compile-custom</goal> </goals> <configuration> <!-- Configuration for a specific goal --> <pluginId>grpc</pluginId> <pluginArtifact> io.grpc:protoc-gen-grpc-java:${grpcVersion}:exe:${os.detected.classifier} </pluginArtifact> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> ... <!-- Core protobuf dependency --> <dependencies> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>${protobufVersion}</version> </dependency> <!-- Another dependency that contains both protobuf definitions and compiled java sources --> <dependency> <groupId>com.google.api.grpc</groupId> <artifactId>proto-google-common-protos</artifactId> <version>1.12.0</version> </dependency> <!-- gRPC dependencies --> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty</artifactId> <version>${grpcVersion}</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>${grpcVersion}</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>${grpcVersion}</version> </dependency> </dependencies> ... </project>