本地运行 Play 服务器时 M1 Mac 出现 UnsatisfiedLinkError

Zac*_*ack 12 java macos scala jna sbt

当利用 LeadIQ 的 play 样板运行新项目时,我们将在低于 5.7.0 版本的旧版本 JNA 中遇到 UnsatisfiedLinkError。

我认为这是由于 ARM M1 架构之间的二进制文件不兼容造成的。怎么解决呢?

这是完整的堆栈跟踪,显示 JNA 二进制文件中的“没有匹配的架构”。

[error] java.lang.UnsatisfiedLinkError: /Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp: dlopen(/Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp, 1): no suitable image found.  Did find:
[error]     /Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp: no matching architecture in universal wrapper
[error]     /Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp: no matching architecture in universal wrapper
[error]     at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
[error]     at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
[error]     at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
[error]     at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
[error]     at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
[error]     at java.base/java.lang.Runtime.load0(Runtime.java:768)
[error]     at java.base/java.lang.System.load(System.java:1837)
[error]     at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:1018)
[error]     at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:988)
[error]     at com.sun.jna.Native.<clinit>(Native.java:195)
[error]     at io.methvin.watchservice.jna.CarbonAPI.<clinit>(CarbonAPI.java:20)
[error]     at io.methvin.watchservice.jna.CFStringRef.toCFString(CFStringRef.java:23)
[error]     at io.methvin.watchservice.MacOSXListeningWatchService.register(MacOSXListeningWatchService.java:127)
[error]     at io.methvin.watchservice.WatchablePath.register(WatchablePath.java:50)
[error]     at io.methvin.watcher.DirectoryWatcher.register(DirectoryWatcher.java:400)
[error]     at io.methvin.watcher.DirectoryWatcher.registerAll(DirectoryWatcher.java:373)
[error]     at io.methvin.watcher.DirectoryWatcher.<init>(DirectoryWatcher.java:193)
[error]     at io.methvin.watcher.DirectoryWatcher$Builder.build(DirectoryWatcher.java:122)
[error]     at play.dev.filewatch.DefaultFileWatchService.watch(DefaultFileWatchService.scala:44)
[error]     at play.dev.filewatch.FileWatchService$$anon$1.watch(FileWatchService.scala:95)
[error]     at play.runsupport.Reloader.<init>(Reloader.scala:443)
[error]     at play.runsupport.Reloader$.reloader$lzycompute$1(Reloader.scala:283)
[error]     at play.runsupport.Reloader$.play$runsupport$Reloader$$reloader$1(Reloader.scala:275)
[error]     at play.runsupport.Reloader$.startDevMode(Reloader.scala:306)
[error]     at play.sbt.run.PlayRun$.devModeServer$lzycompute$1(PlayRun.scala:100)
[error]     at play.sbt.run.PlayRun$.devModeServer$1(PlayRun.scala:83)
[error]     at play.sbt.run.PlayRun$.$anonfun$playRunTask$3(PlayRun.scala:107)
[error]     at play.sbt.run.PlayRun$.$anonfun$playRunTask$3$adapted(PlayRun.scala:67)
[error]     at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] stack trace is suppressed; run last Compile / run for the full output
[error] (Compile / run) java.lang.UnsatisfiedLinkError: /Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp: dlopen(/Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp, 1): no suitable image found.  Did find:
[error]     /Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp: no matching architecture in universal wrapper
[error]     /Users/zackng/Library/Caches/JNA/temp/jna1415930593236960966.tmp: no matching architecture in universal wrapper
[error] Total time: 1 s, completed Dec 15, 2021, 10:36:16 AM
Run Code Online (Sandbox Code Playgroud)

Dan*_*dis 14

有两个与 macOS 和 M1 芯片相关的兼容性问题可能会导致UnsatisfiedLinkErrors.

您遇到的问题与缺乏对aarch64M1 架构的支持有关。此问题已在JNA 5.7.0中修复,升级到该版本或更高版本可以解决该问题。

可能产生此错误的另一个问题与 Apple 如何更改 macOS 11 (Big Sur) 中加载系统库的方式相关,并在未来版本中继续下去。

来自macOS Big Sur 11.0.1 发行说明

作为 macOS Big Sur 11.0.1 中的新增功能,该系统附带了所有系统提供的库的内置动态链接器缓存。作为此更改的一部分,文件系统上不再存在动态库的副本。尝试通过在路径中查找文件或枚举目录来检查动态库是否存在的代码将会失败。相反,通过尝试 dlopen() 路径来检查库是否存在,这将正确检查缓存中的库。

JNA 在版本 5.6.0中修复了此加载问题。

  • 我使用的是 Mac Monterey 12.5.1。使用 JNA 5.8.0。但仍然有同样的问题。任何帮助表示赞赏。我需要更改 Mac 设置吗? (3认同)

Zac*_*ack 11

引用自GitHub

并用 jna-5.8.0.jar 替换 .sbt/boot/scala-2.12.14/org.scala-sbt/sbt/1.5.5/jna- 5.5.0.jar 修复了该问题,因此增加了依赖关系sbt.io 绝对是必需的

基本上删除现有的jna../sbt/1.5.5/jna-...并复制jna版本> = 5.6.0的新jar asjna-v.v.v.jar

具体来说,我使用的是 5.10.0,服务器现在正在运行!:田田:

感谢 Github 用户vbabenkoru和 Elia 帮助我解决了这个问题!

编辑:根据发行说明修改为 5.6.0,感谢 Daniel Widdis 指出!