一.引言
使用 Mac-M1 运行 Spark 程序提示 [FAILED_TO_LOAD_NATIVE_LIBRARY] no native library is found for os.name=Mac and os.arch=aarch64 报错异常:
二.问题分析与解决
1.异常栈分析
根据异常栈的定位看到报错发生在 LoadNativeLibrary 处,即在 jar 文件中加载依赖于OS的本机库:
A.获取 snappyNativeLibrary 地址
其逻辑很简单,首先获取本地 snappyNativeLibrary 地址:
snappyNativeLibraryPath = "/org/xerial/snappy/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
可以通过下述代码获取 OsName 与 ArchName:
println(System.getProperty("os.name") + "\t" + System.getProperty("os.arch"))
MacM1 得到下述结果:
Mac OS X aarch64
B.查找对应文件
对应文件名可以通过下述代码获取:
var snappyNativeLibraryName = System.getProperty("org.xerial.snappy.lib.name")
// Resolve the library file name with a suffix (e.g., dll, .so, etc.)
if (snappyNativeLibraryName == null) snappyNativeLibraryName = System.mapLibraryName("snappyjava")
println(snappyNativeLibraryName)
libsnappyjava.dylib
经过前面 JNI、JNA 的介绍,相信对 dylib 我们并不陌生,其是 MacOS 运行的 C/C++ 动态库的类型,我们通过 maven 依赖查询发现当前 snappy-java 版本下 Mac OS 只有 x86 与 x86_64 没有 aarch64,更不要提 libsnappyjava.dylib 了:
2.依赖解决
A.版本查询
既然是 snapy-java jar - v1.1.2.4 包里不包含对应文件,我们猜测是因为 jar 包版本太低,还不支持 M1,所以尝试更换新版本:
当前 1.1.2.4 版本为 2016 年发布,浅查下 M1 的时间:
B.替换高版本
理论上时间超过 2022年11月11日的都可以,这里采用暴力法,直接更换最新版本尝试,不行再降:
<!--https://mvnrepository.com/artifact/org.xerial.snappy/snappy-java-->
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.8.4</version>
</dependency>
根据 Maven 依赖加载按 pom 顺序加载,所以我们直接将该依赖添加至 pom dependencies 的第一位并执行 maven reimport。重新加载后程序运行正常,再到熟悉的地方看看:
搞定~