[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

浙公網安備 33010602011771號