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
trueto enable generation
-
-
quarkus.generate-code.grpc.descriptor-set.output-dir-
Set this to a value relative to the project’s build directory (i.e.
targetfor Maven,buildfor 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/protoorsrc/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.
Kotlin code generation
protoc also supports generating Kotlin code in addition to the generated Java code.
By default, the Kotlin code generation is enabled if the dependency io.quarkus:quarkus-kotlin is present.
To explicitly en-/disable this feature, set the quarkus.generate-code.grpc.kotlin.generate property in your application.properties file to true or false.
com.google.protobuf:protobuf-kotlin needs to be included as dependency in the project.
|
Skipping code generation
You can skip gRPC code generation using:
-
The
grpc.codegen.skipsystem property:-Dgrpc.codegen.skip=true -
The
quarkus.grpc.codegen.skipproperty in yourapplication.propertiesfile: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.69.1</grpc.version>
<protoc.version>3.25.5</protoc.version>
These properties configure the gRPC version and the protoc version.
Then, add the eu.maveniverse.maven.nisse:plugin3 and the protobuf-maven-plugin configuration to the build section:
<build>
<plugins>
<plugin>
<groupId>eu.maveniverse.maven.nisse</groupId>
<artifactId>plugin3</artifactId>
<version>0.4.0</version>
<executions>
<execution>
<id>inject-properties</id>
<goals>
<goal>inject-properties</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
<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 Nisse 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.
|
In order for the Nisse Maven plugin to generate the correct properties, we need to make sure the nisse.compat.osDetector system
property is set. This can be done by adding the following .mvn/maven.config file:
-Dnisse.compat.osDetector=true
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.5.0</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.
|