You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac M1上已用JNA 5.12.1,Testcontainers仍报UnsatisfiedLink错误

Mac M1上Testcontainers JUnit4测试UnsatisfiedLinkError问题(已升级JNA至5.12.1仍报错)

我在Mac M1上构建基于sbt的项目,使用Testcontainers的JUnit4测试时出现错误。网上多数方案指出是JNA版本过旧(5.6.0之前)导致,于是我将Testcontainers升级到1.18.1版本(该版本自带JNA 5.12.1),依赖配置如下:

"junit" % "junit" % "4.12" % Test,
"org.testcontainers" % "testcontainers" % "1.18.1" % Test,
"org.testcontainers" % "mysql" % "1.18.1" % Test

我执行sbt dependencyTree和sbt test:dependencyTree确认没有旧版JNA引入,当前仅使用5.12.1版本,甚至替换了.sbt文件夹中的JNA版本。

使用的Java是通过sdkman!安装的Zulu 11:

openjdk 11.0.18 2023-01-17 LTS
OpenJDK Runtime Environment Zulu11.62+17-CA (build 11.0.18+10-LTS)
OpenJDK 64-Bit Server VM Zulu11.62+17-CA (build 11.0.18+10-LTS, mixed mode)

现有方案均无效,请问更新至最新库后仍报错的原因是什么?是否有绕过方案(如不使用UnixSocket与Docker通信)?

错误日志如下:

[error] Test com.redacted.my.Test failed: java.lang.UnsatisfiedLinkError: 无法加载库:/Users/myself/Library/Caches/JNA/temp/jna13305103600218314813.tmp, took 0.0 sec
[error]     at java.lang.ClassLoader.loadLibrary(ClassLoader.java:2633)
[error]     at java.lang.Runtime.load0(Runtime.java:768)
[error]     at 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 com.github.dockerjava.transport.DomainSocket.<clinit>(DomainSocket.java:54)
[error]     at com.github.dockerjava.transport.UnixSocket.get(UnixSocket.java:29)
[error]     at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$test$2(DockerClientProviderStrategy.java:175)
[error]     at org.testcontainers.dockerclient.DockerClientProviderStrategy.test(DockerClientProviderStrategy.java:189)
[error]     at org.testcontainers.dockerclient.DockerClientProviderStrategy.tryOutStrategy(DockerClientProviderStrategy.java:266)
[error]     at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$getFirstValidStrategy$5(DockerClientProviderStrategy.java:245)
[error]     at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:176)
[error]     at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
[error]     at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
[error]     at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1632)
[error]     at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
[error]     at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
[error]     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
[error]     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
[error]     at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
[error]     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
[error]     at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
[error]     at org.testcontainers.dockerclient.DockerClientProviderStrategy.getFirstValidStrategy(DockerClientProviderStrategy.java:246)
[error]     at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:150)
[error]     at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:186)
[error]     at org.testcontainers.DockerClientFactory$1.getDockerClient(DockerClientFactory.java:104)
[error]     at com.github.dockerjava.api.DockerClientDelegate.authConfig(DockerClientDelegate.java:109)
[error]     at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:321)
...

问题分析与解决方案

可能的原因

  • JNA本地库架构不匹配:Mac M1是ARM64架构,虽然JNA 5.12.1支持ARM64,但如果JNA下载的本地临时库是x86_64版本(可能是缓存或下载源问题),就会加载失败。你看到的jnaXXX.tmp文件可能是错误架构的版本。
  • Docker Desktop配置问题:Docker Desktop在M1上需要确保是ARM64版本,若运行在x86兼容模式下,可能导致JNA调用Unix Socket时出现架构不兼容。
  • JVM启动参数缺失:Zulu 11在M1上运行时,可能需要明确指定参数强制JNA使用自带的本地库,而非系统或缓存中的旧版本。
  • 缓存权限问题:JNA缓存目录/Users/myself/Library/Caches/JNA/的权限异常,导致无法正确写入或读取临时库文件,进而加载失败。

绕过/解决方法

1. 强制使用Docker TCP连接(绕过Unix Socket)

在sbt中设置测试JVM参数,让Testcontainers使用Docker的TCP端口而非Unix Socket:

Test / javaOptions += "-Dtestcontainers.host=localhost"
Test / javaOptions += "-Dtestcontainers.docker.socket=tcp://localhost:2375"

注意:需先在Docker Desktop的设置中开启"Expose daemon on tcp://localhost:2375 without TLS"选项(路径:Settings -> General 或 Settings -> Docker Engine)。

2. 清理JNA缓存并重新下载

删除JNA缓存目录,让JNA重新下载适配ARM64的本地库:

rm -rf ~/Library/Caches/JNA/

之后重新运行sbt test即可。

3. 添加JVM参数强制JNA使用正确库

在sbt测试配置中添加以下参数:

Test / javaOptions += "-Djna.nosys=true"

jna.nosys=true会禁止JNA使用系统中的本地库,强制使用依赖包中的版本。

4. 验证Docker Desktop架构

确保Docker Desktop是ARM64版本:

  • 打开Docker Desktop -> Settings -> General,确认"Use the new Virtualization framework"已开启;若版本不符,从Docker官网重新下载ARM64安装包。

5. 升级Testcontainers到更高版本

1.18.1之后的版本(如1.19.x及以上)对M1兼容性更好,尝试升级到最新稳定版:

"org.testcontainers" % "testcontainers" % "1.19.7" % Test,
"org.testcontainers" % "mysql" % "1.19.7" % Test

内容的提问来源于stack exchange,提问作者jbx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:32:56