编辑此页面

gRPC 代码生成参考指南

本参考指南解释了如何配置 gRPC 代码生成。建议首先阅读官方 gRPC 指南

启用 gRPC 代码生成

默认情况下,位于 src/main/proto 目录中的 \*.proto 文件在构建过程中会被编译成 Java 源代码。

使用 Maven

要启用 gRPC 代码生成,请将以下依赖项添加到您的项目中

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-grpc</artifactId>
</dependency>

接下来,确保在 Quarkus Maven 插件中启用了 generate-code 阶段

<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>

使用 Gradle

对于 Gradle,将以下依赖项添加到您的项目中

implementation 'io.quarkus:quarkus-grpc'

自定义 proto 目录

默认情况下,假定 \*.proto 文件位于 src/main/proto 目录中。您可以使用 构建描述符 中的 quarkus.grpc.codegen.proto-directory 属性来配置此位置。

对于 Maven,添加以下配置

<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>

对于 Gradle,使用以下配置

quarkus {
    quarkusBuildProperties.put("quarkus.grpc.codegen.proto-directory", "${project.projectDir}/ext/proto")
}

生成描述符集

Protocol Buffers 不包含对其自身类型的描述。因此,如果只有原始消息而没有定义其类型的相应 .proto 文件,则很难提取任何有用的数据。但是,可以使用 protocol buffers 表示 .proto 文件的内容本身。

默认情况下,Quarkus 不会生成这些描述符。Quarkus 提供了几个配置选项来生成它们。这些配置会添加到您的 application.propertiesapplication.yml 文件中

  • quarkus.generate-code.grpc.descriptor-set.generate

    • 设置为 true 以启用生成

  • quarkus.generate-code.grpc.descriptor-set.output-dir

    • 将其设置为相对于项目构建目录的值(即 Maven 的 target,Gradle 的 build

    • Maven 默认值:target/generated-sources/grpc

    • Gradle 默认值:$buildDir/classes/java/quarkus-generated-sources/grpc

  • quarkus.generate-code.grpc.descriptor-set.name

    • 要生成的描述符集文件的名称

    • 默认值:descriptor_set.dsc

配置 gRPC 依赖项代码生成

您可能有包含要编译为 Java 源代码的 *.proto 文件的依赖项。本节介绍如何配置代码生成以在代码生成期间包含这些 \*.proto 文件。

用于导入的 Proto 文件

Protocol Buffers 规范提供了一种导入 proto 文件的方法。Quarkus 代码生成机制允许您通过在 application.properties 中设置 quarkus.generate-code.grpc.scan-for-imports 属性来控制要扫描哪些依赖项以查找可能的导入。您可以将其设置为以下值之一

  • all - 扫描所有依赖项

  • none - 不扫描依赖项,仅使用 src/main/protosrc/test/proto 中定义的内容

  • groupId1:artifactId1,groupId2:artifactId2 - 仅按组 ID 和构件 ID 扫描指定的依赖项。

如果未指定,则该属性默认为 com.google.protobuf:protobuf-java。要覆盖它,请在您的 application.properties 中设置 quarkus.generate-code.grpc.scan-for-imports 属性。例如

quarkus.generate-code.grpc.scan-for-imports=all

来自依赖项的 Proto 文件

在某些情况下,您可能想使用来自其他项目的 proto 文件来生成 gRPC 存根。为此

  1. 在您的项目中添加对包含 proto 文件的构件的依赖项。

  2. application.properties 中,指定您要扫描 proto 文件的依赖项。

quarkus.generate-code.grpc.scan-for-proto=<groupId>:<artifactId>

该属性的值可以是 none(默认值),也可以是逗号分隔的 groupId:artifactId 坐标列表。

如果依赖项包含许多 proto 文件,并且您只想为其中的一部分生成类,则可以为每个依赖项指定 glob 模式。要匹配的路径是相对于依赖项中 src/main/resources 路径的路径。例如

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

请注意,属性键中的 : 字符必须转义。

Kotlin 代码生成

除了生成的 Java 代码之外,protoc 还支持 生成 Kotlin 代码

默认情况下,如果存在依赖项 io.quarkus:quarkus-kotlin,则会启用 Kotlin 代码生成。

要显式启用/禁用此功能,请在您的 application.properties 文件中将 quarkus.generate-code.grpc.kotlin.generate 属性设置为 truefalse

com.google.protobuf:protobuf-kotlin 需要作为依赖项包含在项目中。

跳过代码生成

您可以使用以下方法跳过 gRPC 代码生成

  1. grpc.codegen.skip 系统属性:-Dgrpc.codegen.skip=true

  2. 您的 application.properties 文件中的 quarkus.grpc.codegen.skip 属性:quarkus.grpc.codegen.skip=true

使用 protobuf-maven-plugin 从 proto 生成 Java 文件

或者,要为 proto 文件生成存根,您可以使用 protobuf-maven-plugin。但是,建议使用 Quarkus 支持,除非您有特殊需求。

为此,请在 <properties> 部分中定义以下属性

<grpc.version>1.69.1</grpc.version>
<protoc.version>3.25.5</protoc.version>

这些属性配置 gRPC 版本和 protoc 版本。

然后,将 eu.maveniverse.maven.nisse:plugin3protobuf-maven-plugin 配置添加到 build 部分

<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 protobuf-maven-plugin 从您的 gRPC 服务定义(proto 文件)生成存根类。
2 类生成使用工具 protoc,它是特定于操作系统的。这就是为什么我们使用 Nisse Maven 插件来定位与操作系统兼容的可执行文件。

注意:此配置指示 protobuf-maven-plugin 生成默认 gRPC 类和使用 Mutiny 的类,以适应 Quarkus 开发体验。

当使用 protobuf-maven-plugin 而不是 quarkus-maven-plugin 时,您每次更新 proto 文件时都需要重新生成类(使用 mvn compile)。

为了让 Nisse Maven 插件生成正确的属性,我们需要确保设置了 nisse.compat.osDetector 系统属性。这可以通过添加以下 .mvn/maven.config 文件来完成

-Dnisse.compat.osDetector=true

使用来自依赖项的生成的 gRPC 类

当 gRPC 类(是从 proto 文件生成的类)位于应用程序的依赖项中时,该依赖项需要 Jandex 索引。您可以使用 jandex-maven-plugin 创建 Jandex 索引。有关此主题的更多信息,请参阅 CDI 指南的 Bean 发现 部分。

<build>
    <plugins>
        <plugin>
            <groupId>io.smallrye</groupId>
            <artifactId>jandex-maven-plugin</artifactId>
            <version>3.3.2</version>
            <executions>
                <execution>
                <id>make-index</id>
                <goals>
                    <goal>jandex</goal>
                </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

如果您使用 Gradle,则可以使用以下配置

plugins {
    id 'org.kordamp.gradle.jandex' version '1.1.0'
}
建议将 proto 文件打包在依赖项中,而不是生成的类,以便 Quarkus 可以生成优化的类。有关更多信息,请参阅 专用部分

参数文件

protoc 命令行超过最大命令长度时,您可以要求 Quarkus 使用参数文件将参数传递给 protoc 命令。

要启用此功能,请在您的 application.properties 文件中将 quarkus.generate-code.grpc.use-arg-file 属性设置为 true

如果您在 Windows 上,并且命令行超过 8190 个字符,Quarkus 会自动使用参数文件将参数传递给 protoc 命令。

本地与下载的 protoc

为了生成 gRPC 类,Quarkus 使用来自 com.google.protobuf 组 id 的 protoc 构件。但是,为了确保对各种平台的支持,Quarkus 会自动下载 所有 可能的 protoc 构件变体。此外,Quarkus 还会下载用于生成 Java 中 gRPC 类的 protoc 和插件。例如,即使您使用 Linux,Quarkus 也会下载 Windows 和 MacOS 的 protoc 和 Java 插件构件。

下表列出了 protoc 和插件构件的不同变体

平台 分类符 依赖项

Linux/ARM64

linux-aarch_64

com.google.protobuf:protoc:VERSION:exe:linux-aarch_64io.grpc:protoc-gen-grpc-java:VERSION:exe:linux-aarch_64

Linux/Power PC 64 位

linux-ppcle_64

com.google.protobuf:protoc:VERSION:exe:linux-ppcle_64io.grpc:protoc-gen-grpc-java:VERSION:exe:linux-ppcle_64

Linux/S390 64 位

linux-s390_64

com.google.protobuf:protoc:VERSION:exe:linux-s390_64io.grpc:protoc-gen-grpc-java:VERSION:exe:linux-s390_64

Linux/x86 32 位

linux-x86_32

com.google.protobuf:protoc:VERSION:exe:linux-x86_32io.grpc:protoc-gen-grpc-java:VERSION:exe:linux-x86_32

Linux/x86 64 位

linux-x86_64

com.google.protobuf:protoc:VERSION:exe:linux-x86_64io.grpc:protoc-gen-grpc-java:VERSION:exe:linux-x86_64

Mac osx/ARM64

osx-aarch_64

com.google.protobuf:protoc:VERSION:exe:osx-aarch_64io.grpc:protoc-gen-grpc-java:VERSION:exe:osx-aarch_64

Mac osx/x86 64 位

osx-x86_64

com.google.protobuf:protoc:VERSION:exe:osx-x86_64io.grpc:protoc-gen-grpc-java:VERSION:exe:osx-x86_64

Windows x86 32 位

windows-x86_32

com.google.protobuf:protoc:VERSION:exe:windows-x86_32io.grpc:protoc-gen-grpc-java:VERSION:exe:windows-x86_32

Windows x86 64 位

windows-x86_64

com.google.protobuf:protoc:VERSION:exe:windows-x86_64io.grpc:protoc-gen-grpc-java:VERSION:exe:windows-x86_64

由于 protoc 和插件的打包(使用分类符),无法单独排除不需要的平台。

但是,您可以完全排除 protoc 依赖项,并使用 quarkus.grpc.protoc-path 系统属性来配置安装在您机器上的 protoc 可执行文件的路径。因此,您不需要下载任何 protoc 变体

步骤 1:排除 protoc
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-grpc</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protoc</artifactId>
        </exclusion>
    </exclusions>
</dependency>
步骤 2:传递 quarkus.grpc.protoc-path 属性
mvn clean quarkus:dev -Dquarkus.grpc.protoc-path=/path/to/protoc
使用此方法需要本地安装 protoc。它不会下载任何 protoc 构件。
不幸的是,这仅适用于 protoc,而不适用于 Java 插件。Java 插件始终会下载。

相关内容