ZMQ 轮询在 IntelliJ 下的应用程序和测试中有效,但在 sbt/scalatest 下失败

ZMQ poll works in app and test under IntelliJ but fails under sbt/scalatest

我正在为 ZMQ 使用 org.zeromq java 库,它在生产部署和我 运行 在 IntelliJ 内部测试时效果很好,但是如果我尝试 运行 在同一台机器上通过命令行通过 sbt 进行的相同测试失败了:

java.lang.AbstractMethodError: com.sun.jna.Structure.getFieldOrder()Ljava/util/List;
    at com.sun.jna.Structure.fieldOrder(Structure.java:868) ~[jna-4.0.0.jar:4.0.0 (b2)]
    ... (8 lines omitted)
    at org.zeromq.zmq_msg_t.<init>(zmq_msg_t.java:21) ~[zeromq-scala-binding_2.10-0.0.7.jar:0.0.7]
    at org.zeromq.ZMQ$Socket.newZmqMessage(ZMQ.java:453) ~[zeromq-scala-binding_2.10-0.0.7.jar:0.0.7]
    at org.zeromq.ZMQ$Socket.send(ZMQ.java:368) ~[zeromq-scala-binding_2.10-0.0.7.jar:0.0.7]

测试就是这样:

class ZeroMQSpec extends FlatSpec with Matchers with LazyLogging {

  "zeroMQ" should "be able to just send something" in {
    val context = ZMQ.context(1)
    val socket = context.socket(ZMQ.PAIR)
    socket.bind("inproc://zmqtest")
    logger.debug("start polling")
    try {
      socket.send(Array[Byte](1, 2), 0)
      logger.debug("done polling")
    } catch {
      case e: Throwable => logger.error("ZMQ failed", e)
    }
  }

send 只是一个例子。 recvpoll.

也是如此

由于在同一台机器上的 IntelliJ 下 运行 和 ZMQ 也可以在生产代码中运行时相同的测试通过了,所以它似乎与安装的本机 ZMQ 无关,而是 JVM 如何绑定到它。不幸的是,我不知道如何进一步解决这个问题。

更新

在@cdshines 问题的提示下,我查看了类路径中的 JNA 需要什么才能工作并通过 this,我需要 platform.jar 和 jna.jar。在 IntelliJ 中,它们都来自我的常春藤缓存:

file:/Users/arne/.ivy2/cache/net.java.dev.jna/jna/jars/jna-3.0.9.jar
file:/Users/arne/.ivy2/cache/net.java.dev.jna/jna/jars/jna-4.0.0.jar
file:/Users/arne/.ivy2/cache/net.java.dev.jna/platform/jars/platform-3.4.0.jar

我认为 SBT 也应该解决这个问题。既然不是,有没有办法强制SBT这样做?

更新 2

已添加

"net.java.dev.jna" % "jna" % "4.0.0" % "test",
"net.java.dev.jna" % "jna-platform" % "4.0.0" % "test",

我的依赖。行为无变化

您的 zeromq-scala-binding 版本取决于 JNA 版本 3.0.9,但您 运行 它与二进制不兼容的 JNA 版本 4.0.0

您需要从引入 JNA 4 的任何其他依赖项中排除它。您可以使用 sbt-dependency-graph 找出是哪个依赖项。

通常情况下,我会害怕通过强制使用 JNA 3 来破坏另一个依赖项,但你说它在生产中有效,所以你应该没问题。