I have an sbt-based project that I am trying to build on my Mac M1, and its tests (JUnit 4) based on testcontainers are failing with the error below. Most solutions I found online suggested that the JNA version could be old (pre-5.6.0), so I upgraded test containers to the latest version, which includes an (almost) latest version of JNA 5.12.1:
"junit" % "junit" % "4.12" % Test,
"org.testcontainers" % "testcontainers" % "1.18.1" % Test,
"org.testcontainers" % "mysql" % "1.18.1" % Test
I did sbt dependencyTree
and sbt test:dependencyTree
to make sure the old JNA is not included from somewhere else, and the only version included is 5.12.1.
I even replaced the JNA version in my .sbt
folder to make sure it isn't somehow being picked up from there.
I am running Java 11 (through sdkman!)
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)
At this point I am a bit at a loss what else to try. Existent solutions don't seem to work. What could be the reason I am still getting this error, even after updating to the latest testcontainers
and jna
libraries?
Is there any workaround I could do to avoid this (maybe not use UnixSockets at all to communicate with Docker)?
[error] Test com.redacted.my.Test failed: java.lang.UnsatisfiedLinkError: Can't load library: /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)
...
For those who encounter the same issue, my problem was that although I was explicitly excluding JNA dependencies from older libraries that had not yet been updated, and made sure that only the latest version of JNA was included, there might still be libraries that have the same classes directly in the JAR file in "shaded" mode.
In my case, the culprit was io.kamon:kamon-bundle
.
Although shading is by and large considered bad practice, some major libraries still do it, causing these library conflicts, without an easy way to resolve.
If you encounter this problem, and updating to the latest testcontainers
or JNA explicitly doesn't solve it, and excluding it from other JAR files still fails, you can either use a good IDE like IntelliJ to figure out which JAR files are providing the same class, or otherwise use the -verbose:class
JVM switch to figure out from where each class is being loaded via the command line.