0

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)
...
jbx
  • 21,365
  • 18
  • 90
  • 144
  • How you installed docker? which version? version of the JDK? how you installed the JDK? [homebrew](https://brew.sh/)? [sdkman](https://sdkman.io/)? If you check the docs of testcontainer, the section [Junit 5 Quickstart](https://www.testcontainers.org/quickstart/junit_5_quickstart/) assuming you are using that framework test, you also need the junit dependency from testcontainers. Could you edit your post and if it is possible provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – Gastón Schabas Jun 02 '23 at 13:21
  • @GastónSchabas thanks for your reply. I added the details. Yes sdkman, Java 11 (Zulu). I am using junit4, which shouldn't need anything in addition. (This works fine on non-m1 platforms, so if there was a missing dependency it would have failed earlier). I will see if I can somehow generate another minimal reproducable example. – jbx Jun 02 '23 at 13:52
  • As you said, looks like an issue related with **JNA** version and **Mac M1**. Here there is an [issue](https://github.com/testcontainers/testcontainers-java/issues/6775) about someone saying that `JNA 5.12.1` didn't work. You have also [issue 3834](https://github.com/testcontainers/testcontainers-java/issues/3834#issuecomment-788995236) and [issue 3810](https://github.com/testcontainers/testcontainers-java/issues/3810#issuecomment-849512152) where `JNA 5.7.0` worked on Mac M1. Hope that helps – Gastón Schabas Jun 02 '23 at 14:52
  • @GastónSchabas of course I looked around these issues before I asked here. The first issue is saying that JNA 5.12.1 should work (not didn't work). Issue 3834 is indicating that an older JNA version was pulled by elasticsearch. I used `sbt test:dependencyTree` to check this is not happening. I have other projects using testcontainers 1.16.0 and they work fine. I can't figure out what's wrong with this project. I tried to regenerate it with a minimal reproducable example but it works fine. I am trying to figure out what else I could check. – jbx Jun 05 '23 at 10:15
  • I can't find any comment saying that `JNA 5.12.x` worked. Only [5.7.0](https://github.com/testcontainers/testcontainers-java/issues/3834#issuecomment-997496840), [5.8.0](https://github.com/testcontainers/testcontainers-java/issues/3834#issuecomment-1255224001) and [5.10.x](https://github.com/testcontainers/testcontainers-java/issues/3834#issuecomment-1182636995). There is also a comment about [using mariadb instead of mysql](https://github.com/testcontainers/testcontainers-java/issues/3834#issuecomment-796754296). – Gastón Schabas Jun 05 '23 at 15:22
  • @GastónSchabas well the last comment on that issue was 'Can you please try using net.java.dev.jna:jna:5.12.1?' not that it didn't work. I am starting to suspect that maybe some dependency is including the old JNA classes directly rather than as a separate dependency, which is why I cant see it with dependencyTree. I did try a separate project with testcontainers and mysql and it worked, which is why i am starting to suspect this. Not sure how I can find out easily. – jbx Jun 05 '23 at 20:46

1 Answers1

0

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.

jbx
  • 21,365
  • 18
  • 90
  • 144