gRPC code generation reference guide
This reference guide explains how to configure gRPC code generation. It is recommended to read the official gRPC guide first.
Enabling gRPC code generation
By default, \*.proto
files located in the src/main/proto
directory are compiled into Java sources during the build process.
Using Maven
To enable gRPC code generation, add the following dependency to your project:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc</artifactId>
</dependency>
Next, ensure that the generate-code
phase is enabled in the Quarkus Maven plugin:
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
Customizing the proto directory
By default, it is assumed that the \*.proto
files are located in the src/main/proto
directory.
You can configure this location using the quarkus.grpc.codegen.proto-directory
property in your build descriptor.
With Maven, add the following configuration:
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
<configuration>
<properties>
<quarkus.grpc.codegen.proto-directory>${project.basedir}/ext/proto</quarkus.grpc.codegen.proto-directory>
</properties>
</configuration>
</execution>
</executions>
</plugin>
With Gradle, use the following configuration:
quarkus {
quarkusBuildProperties.put("quarkus.grpc.codegen.proto-directory", "${project.projectDir}/ext/proto")
}
Generating Descriptor Set
Protocol Buffers do not contain descriptions of their own types. Thus, given only a raw message without the corresponding .proto file defining its type, it is difficult to extract any useful data. However, the contents of a .proto file can itself be represented using protocol buffers.
By default, Quarkus does not generate these descriptors. Quarkus does provide several configuration options for generating them. These would be added to your application.properties
or application.yml
file:
-
quarkus.generate-code.grpc.descriptor-set.generate
-
Set to
true
to enable generation
-
-
quarkus.generate-code.grpc.descriptor-set.output-dir
-
Set this to a value relative to the project’s build directory (i.e.
target
for Maven,build
for Gradle) -
Maven default value:
target/generated-sources/grpc
-
Gradle default value:
$buildDir/classes/java/quarkus-generated-sources/grpc
-
-
quarkus.generate-code.grpc.descriptor-set.name
-
Name of the descriptor set file to generate
-
Default value:
descriptor_set.dsc
-
Configuring gRPC code generation for dependencies
You may have dependencies that contain *.proto
files you want to compile to Java sources.
This section explains how to configure code generation to include these \*.proto
files during code generation.
Proto files for imports
The Protocol Buffers specification provides a way to import proto
files.
The Quarkus code generation mechanism lets you control the scope of dependencies to scan for possible imports by setting the quarkus.generate-code.grpc.scan-for-imports
property in your application.properties
.
You can set it to one of the following values:
-
all
- scan all dependencies -
none
- don’t scan dependencies, use only what is defined insrc/main/proto
orsrc/test/proto
-
groupId1:artifactId1,groupId2:artifactId2
- scan only the specified dependencies by group ID and artifact ID.
If not specified, the property defaults to com.google.protobuf:protobuf-java
.
To override it, set the quarkus.generate-code.grpc.scan-for-imports
property in your application.properties
.
For example:
quarkus.generate-code.grpc.scan-for-imports=all
Proto files from dependencies
In some cases, you may want to use proto
files from a different project to generate gRPC stubs.
To do this:
-
Add a dependency on the artifact that contains the proto file to your project.
-
In
application.properties
, specify the dependencies you want to scan for proto files.
quarkus.generate-code.grpc.scan-for-proto=<groupId>:<artifactId>
The value of the property can be none
, which is the default, or a comma-separated list of groupId:artifactId
coordinates.
If the dependency contains many proto files, and you want to generate classes for only a subset of them, you can specify glob patterns per dependency.
The paths to match are relative to the src/main/resources
path in the dependency. For example:
quarkus.generate-code.grpc.scan-for-proto-include."<groupId>:<artifactId>"=foo/**,bar/**,banana/a-proto.proto
quarkus.generate-code.grpc.scan-for-proto-exclude."<groupId>:<artifactId>"=foo/private/**,bar/another-proto.proto
Note that :
characters in the property keys must be escaped.
Skipping code generation
You can skip gRPC code generation using:
-
The
grpc.codegen.skip
system property:-Dgrpc.codegen.skip=true
-
The
quarkus.grpc.codegen.skip
property in yourapplication.properties
file:quarkus.grpc.codegen.skip=true
Generating Java files from proto with the protobuf-maven-plugin
Alternatively, to generate stubs for proto
files, you can use the protobuf-maven-plugin
.
However, it’s recommended to use Quarkus support unless you have a specific need.
To do this, define the following properties in the <properties>
section:
<grpc.version>1.65.1</grpc.version>
<protoc.version>3.25.5</protoc.version>
These properties configure the gRPC version and the protoc
version.
Then, add the os-maven-plugin
extension and the protobuf-maven-plugin
configuration to the build
section:
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${os-maven-plugin-version}</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId> (1)
<version>${protobuf-maven-plugin-version}</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact> (2)
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
<protocPlugins>
<protocPlugin>
<id>quarkus-grpc-protoc-plugin</id>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc-protoc-plugin</artifactId>
<version>{quarkus-version}</version>
<mainClass>io.quarkus.grpc.protoc.plugin.MutinyGrpcGenerator</mainClass>
</protocPlugin>
</protocPlugins>
</configuration>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-compile</goal>
<goal>test-compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... -->
</plugins>
</build>
1 | The protobuf-maven-plugin generates stub classes from your gRPC service definition (proto files). |
2 | Class generation uses the tool protoc , which is OS-specific. This is why we use the os-maven-plugin to target the executable compatible with the operating system. |
Note: This configuration instructs the protobuf-maven-plugin
to generate default gRPC classes and classes using Mutiny to fit with the Quarkus development experience.
When using protobuf-maven-plugin , instead of the quarkus-maven-plugin , you need to re-generate classes (using mvn compile ) every time you update the proto files.
|
Using generated gRPC classes from dependencies
When gRPC classes, which are classes generated from proto
files, are in a dependency of the application, the dependency needs a Jandex index.
You can create a Jandex index using the jandex-maven-plugin
.
More information on this topic can be found in the Bean Discovery section of the CDI guide.
<build>
<plugins>
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.2.3</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
If you are using Gradle, you can use the following configuration:
plugins {
id 'org.kordamp.gradle.jandex' version '1.1.0'
}
It is recommended to package the proto files in a dependency instead of the generated classes, so Quarkus can generate optimized classes.
Refer to the dedicated section for more information.
|
Argument files
When the protoc
command line exceeds the maximum command length, you can ask Quarkus to use an argument file to pass the arguments to the protoc
command.
To enable this feature, set the quarkus.generate-code.grpc.use-arg-file
property in your application.properties
file to true
.
If you are on Windows, and the command line exceeds 8190 characters, Quarkus automatically uses an argument file to pass the arguments to the protoc
command.
Local vs. Downloaded protoc
To generate gRPC classes, Quarkus uses the protoc
artifact from the com.google.protobuf
group id.
However, to ensure the support of various platforms, Quarkus automatically downloads all the possible variants of the protoc
artifact.
In addition, Quarkus downloads both protoc
and the plugin used to generate gRPC classes in Java.
For example, even if you are using Linux, Quarkus downloads the protoc
and the Java plugin artifacts for Windows and MacOS.
The next table lists the different variants of the protoc
and plugin artifacts:
Platform | Classifier | Dependencies |
---|---|---|
Linux/ARM64 |
|
|
Linux/Power PC 64 bits |
|
|
Linux/S390 64 bits |
|
|
Linux/x86 32bits |
|
|
Linux/x86 64bits |
|
|
Mac osx/ARM64 |
|
|
Mac osx/x86 64bits |
|
|
Windows x86 32 bits |
|
|
Windows x86 64 bits |
|
|
Because of the packaging of protoc
and the plugin (using classifier), it’s not possible to exclude undesired platforms individually.
You can, however, exclude the protoc
dependency altogether and use the quarkus.grpc.protoc-path
system property to configure the path to the protoc
executable installed on your machine.
Thus, you don’t need to download any protoc
variants:
protoc
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc</artifactId>
<exclusions>
<exclusion>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
</exclusion>
</exclusions>
</dependency>
quarkus.grpc.protoc-path
property:mvn clean quarkus:dev -Dquarkus.grpc.protoc-path=/path/to/protoc
Using this approach requires to have protoc installed locally. It will not download any protoc artifact.
|
Unfortunately, this only works for protoc and not for the Java plugin. The Java plugin is always downloaded.
|