未能使用激活器加载一个本地库(Play Framework)。

 2023-01-19    359  

问题描述

我正在尝试在我的Play 2.4.x应用程序中加载本地库.我写了一个简单的测试,在IDE(Intellij)和SBT中都可以正常工作.在两种情况下,我都设置java.library.path以使测试运行.

在IDE中,我在测试运行配置中设置-Djava.library.path=$USER_HOME$/dev/lindoapi/bin/linux64

未能使用激活器加载一个本地库(Play Framework)。

根据SBT文档,我的build.sbt正在分配JVM并设置java.library.path.

javaOptions += "-Djava.library.path=/home/aczerwon/dev/lindoapi/bin/linux64"

fork := true

以下测试在IDE和activator test中都很好.

class LindoApiSpec extends Specification {

  System.loadLibrary("lindojni")

  "The Lindo API" should {

    "have a valid license" in {
      val lindo = new LindoEnvironment()
      lindo.apiVerion() must beSuccessfulTry.withValue("LINDO API Version 9.0.2120.225")
    }

}

在测试上下文之外,我将本机库加载到Play的启动生命周期中.

object Global extends GlobalSettings {

  override def beforeStart(app: Application) = {
    System.loadLibrary("lindojni")
  }

}

当我从WebAPI(activator ~run)调用相同的方法时,我会收到UnsatisfiedLinkError错误.

1) Error injecting constructor, java.lang.UnsatisfiedLinkError: no lindojni in java.library.path
  at play.api.GlobalPlugin.<init>(GlobalSettings.scala:262)
  at play.api.GlobalPlugin.class(GlobalSettings.scala:262)
  while locating play.api.GlobalPlugin

Web API看起来像这样:

class OptimizationApi extends Controller {

  def version() = Action {
    val lindo = new LindoEnvironment()
    lindo.apiVerion() match {
      case Success(version) => Ok(version)
      case Failure(e) => BadRequest(e.getMessage)
    }
  }

}

我以为我的build.sbt会分叉JVM并为 java.library.path设置 test 和 run上下文.关于我做错了什么的线索?

新信息

当我启动activator -Djava.library.path=$USER_HOME$/dev/lindoapi/bin/linux64或设置java_opts时,在启动生命周期通行证中呼叫System.loadLibrary(…).我仍然得到UnsatisfiedLinkError,但是当我通过JNI拨打本地库时,它会发生.很奇怪.

推荐答案

我找到了问题的解决方案在这里.

本地库及其Java对应物必须在同一类加载程序中.

创建类似于:

的类

public final class PlayNativeLibraryLoader {
    public static void load(String libraryPath) {
        System.load(libraryPath);
    }
}

现在您可以在Play启动生命周期中使用它.

object Global extends GlobalSettings {

  override def beforeStart(app: Application) = {
    PlayNativeLibraryLoader.load(app.getFile("./lib/lindoapi/linux64/liblindojni.so").getPath)
    Logger.info("Lindo native library loaded")
  }

}

以上所述是小编给大家介绍的未能使用激活器加载一个本地库(Play Framework)。,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25812.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。