[Mac] 从Windows切换到ARM机器开发-Protobuf 篇

背景

使用Mac M4芯片的机器,在IDEA开发Java项目,遇到一部分问题,做一下先行记录。

报错1

protobuf 插件报错:protoc:exe:osx-aarch_64:3.12.0 丢失

[ERROR] Failed to execute goal org.xolstice.maven.plugins:protobuf-maven-plugin:0.6.1:compile (default-cli) on project grpc: Unable to resolve artifact: Missing:
[ERROR] ----------
[ERROR] 1) com.google.protobuf:protoc:exe:osx-aarch_64:3.12.0

已经尝试过网络上的办法:改 os.detected.classifier 则报错:
error=86, Bad CPU type in executable

protobuf-java 在 3.17.x 以后的版本已经支持了ARM芯片架构。因此不需要修改 os.detected.classifier

建议直接升级 插件内所使用的 protoc 版本。3.x 的最后一个版本是 3.17.6,所以配置相应的插件和库。

另外:插件就叫这个名,即便是后缀是 exe,不用安装 Rosetta。

slankka@MacMini-M4 protoc-plugins % file protoc-3.25.6-osx-aarch_64.exe 
protoc-3.25.6-osx-aarch_64.exe: Mach-O 64-bit executable arm64
<plugin>
  <groupId>org.xolstice.maven.plugins</groupId>
  <artifactId>protobuf-maven-plugin</artifactId>
  <version>0.6.1</version>
  <configuration>
    <protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
    <protocArtifact>
com.google.protobuf:protoc:3.25.6:exe:${os.detected.classifier}
    </protocArtifact>
  </configuration>
</plugin>

顺便一提:protoc-gen-java-grpc也支持Apple ARM芯片,至少1.43+

<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.43.0:exe:${os.detected.classifier}</pluginArtifact>

报错2

java.lang.NoClassDefFoundError: com/google/protobuf/MapFieldReflectionAccessor

原因:项目内,存在多个版本的 protobuf-java,间接或者直接包含。

Google Protobuf相关:

protobuf-java-3.25.6 是 Protobuf 3.x 的最后一个版本。(截至目前2025.02.12)

<dependency>
  <groupId>com.google.protobuf</groupId>
  <artifactId>protobuf-java</artifactId>
  <version>3.25.6</version>
</dependency>
<dependency>
  <groupId>com.google.protobuf</groupId>
  <artifactId>protobuf-java-util</artifactId>
  <version>3.25.6</version>
</dependency>

第三方:

<dependency>
  <groupId>com.hubspot.jackson</groupId>
  <artifactId>jackson-datatype-protobuf</artifactId>
  <version>0.9.17</version>
</dependency>

问题3

如果项目涉及大数据,例如访问 Hadoop 集群的API,遇到这个问题,需要赶紧降级 protobuf 版本,只要服务端Hadoop(Hdfs、Yarn等)用了低版本(Hadoop 至今在使用 Protobuf 2.5.0)

可参考 apache drill 的 PR(在下方有链接),此框架锁定了 protobuf-java: 3.25.5。

把 protobuf-java降低至 3.25.5 即可解决。

Caused by: java.lang.UnsupportedOperationException: As of 2022/09/29 (release 21.7) makeExtensionsImmutable should not be called from protobuf gencode. 
If you are seeing this message, your gencode is vulnerable to a denial of service attack. You should regenerate your code using protobuf 25.6 or later. 
Use the latest version that meets your needs. However, if you understand the risks and wish to continue with vulnerable gencode, you can set the system 
property `-Dcom.google.protobuf.use_unsafe_pre22_gencode` on the command line. See security vulnerability: https://github.com/protocolbuffers/protobuf/s
ecurity/advisories/GHSA-h4h5-3hr4-j3g2
        at com.google.protobuf.GeneratedMessage.warnPre22Gencode(GeneratedMessage.java:327)
        at com.google.protobuf.GeneratedMessage.makeExtensionsImmutable(GeneratedMessage.java:333)
        at org.apache.hadoop.ipc.protobuf.RpcHeaderProtos$RpcResponseHeaderProto.<init>(RpcHeaderProtos.java:3376)
        at org.apache.hadoop.ipc.protobuf.RpcHeaderProtos$RpcResponseHeaderProto.<init>(RpcHeaderProtos.java:3262)

问题4

java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/PropertyNamingStrategies$NamingBase

如果使用了 jackson-datatype-protobuf ,则尤其需要注意, protobuf 类序列化为 Jackson 的第三方库,所引用的 Jackson版本也有会链接错误:
注意:jackson-datatype-protobuf 的版本,在0.9.14 还支持 Jackson-2.12 以下的版本,在后续的版本,已经至少需要 jackson-2.12。

之所以出现这个问题:因为项目中使用了 SpringBoot 全家桶,且版本不容易升级,所以含有 jackson-2.10,不满足 jackson-datatype-protobuf 新版的要求,真是左右为难。

<dependency>
  <groupId>com.hubspot.jackson</groupId>
  <artifactId>jackson-datatype-protobuf</artifactId>
  <version>0.9.17</version> <!--0.9.14才能兼容 jackson 2.10 -->
</dependency>

参考资料

Github.com grpc-java
Github.com Apache Drill PR-2977
Github.com Jackson-datatype-protobuf
Github.com Grpc-Java

posted @ 2025-03-18 11:23  一杯半盏  阅读(400)  评论(0)    收藏  举报