[protocolbuffers/protobuf]protoc 3.18.0 生成的代码与 protobuf-java 3.17.3(及更早版本)不兼容

2024-05-11 342 views
3

您使用什么版本的 protobuf 以及什么语言? 版本:3.18.0(protoc 和 protobuf-java) 语言:Java

什么操作系统(Linux、Windows...)和版本? 视窗、Linux

您使用什么运行时/编译器(例如,python 版本或 gcc 版本) Gradle Protobuf 插件 0.8.17

你做了什么? 将 Protobuf 从 更新为 后3.17.33.18.0我们可以看到以下错误:

D:\Work\public\rabbitmq-scala-client\extras-scalapb\build\generated\source\proto\test\java\com\avast\clients\rabbitmq\test\ExampleEvents.java:226: error: cannot find symbol
      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(fileId_)) {
                                                 ^
  symbol:   method isStringEmpty(java.lang.Object)
  location: class com.google.protobuf.GeneratedMessageV3

看起来生成的代码尝试调用com.google.protobuf.GeneratedMessageV3.isStringEmpty该方法protected,因此此处无法访问。编译失败。

拉取请求将 Protobuf 更新到 3.18.0,从而重现此错误:https://github.com/avast/rabbitmq-scala-client/pull/140

您期望看到什么 生成的代码没有编译错误。

你看到了什么? 编译错误。

关于您的项目/环境我们还应该了解的其他信息

回答

4

我很惊讶没有测试发现这一点。我们没有任何编译生成的 Java 代码的测试吗?

0

是的,几乎所有测试都编译原型 AFAIK。

1

我认为我们现在应该回滚#7526。

1

SGTM

5

尽管从技术上来说这是一个 API 重大变化

4

公开可能是未来的出路。

6

我认为我们现在可以恢复协议中的更改并将更改保留在GenerateMessageV3.java 中。这可以避免更改已发布的 API。

7

您能否确认您使用的是 3.18.0 运行时以及协议?

2

您还可以验证 gradle 插件是否提供了可能在类路径中获取的旧运行时吗?

0

您好,我们在 Gradle 项目中有这些片段:

classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.17'

protobufVersion = "3.18.0"

api "com.google.protobuf:protobuf-java:$protobufVersion"

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:$protobufVersion"
    }
}

3.18.0使用 IDEA 声明依赖关系。 图像

我也尝试执行下载的版本protoc,它的版本似乎是正确的:

C:\Users\augustyn\.gradle\caches\modules-2\files-2.1\com.google.protobuf\protoc\3.18.0\1641536d5a8bbfca63aad8b5284b213c0fb2ee1>protoc-3.18.0-windows-x86_64.exe --version
libprotoc 3.18.0
2

好吧,我刚刚找到了根本原因,我很抱歉。我迷失在这个rabbitmq-scala-client项目中 - 有两个子项目:

  • extras-protobuf- 效果很好
  • extras-scalapb- 这是有问题的。问题是我们没有protobuf-java明确定义依赖关系,我们是通过 获取此依赖关系scalapb,并且它附带3.15.8.

所以问题实际上是3.18.0早期3.x版本之间存在重大变化。生成的代码protoc 3.18.0不能与早期3.x protobuf-java版本一起编译。我将相应地更新此问题的摘要。

6

嗯,这就解释了这一点。我不认为我们承诺生成的 Java 代码可以针对该库的早期版本进行编译。不过,这有点边缘条件。