scala - 不满意链接错误 : How to load native library of opencv when running play application?

标签 scala opencv playframework sbt

我正在运行一个使用 opencv 和 scala 的游戏框架应用程序。当我运行该应用程序时,我从 VideoCapture 收到一个 UnsatisfiedLinkError,那么我该如何正确加载 opencv 库?

当我使用 opencv 中的类运行测试时,一切正常。我总是设置 System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 并正确定义 java.path.library 参数。但是当我运行 Play 应用程序时,这与测试不同。

在其他帖子中,人们一直在使用来自 play 的抽象 GlobalSetting 类并在 beforeStart() 方法中加载库来解决这个问题。但这已被弃用,现在 Play 建议进行热切绑定(bind)。我已经尝试创建一个 Eager 加载程序,以便在我启动服务器时首先运行,我以与运行测试相同的方式加载库。此类中的代码按预期首先运行,但它并没有解决我的问题。

我还尝试在我拥有的不同 Controller 和我使用 VideoCapture() 的类中加载库,但没有任何效果。此外,我尝试创建一个 sbt 任务,我在其中加载了库但没有成功。

class EagerLoaderModule extends AbstractModule {
  override def configure(): Unit = bind(classOf[StartUpService]).asEagerSingleton()
}
final class StartUpService {

  def loadedLibs: Seq[String] = {
    val libs = classOf[ClassLoader].getDeclaredField("loadedLibraryNames")
    libs.setAccessible(true)
    import scala.collection.JavaConverters._
    libs.get(ClassLoader.getSystemClassLoader)
      .asInstanceOf[java.util.Vector[String]]
      .asScala
  }

  def loadOpenCVOnDemand(): Unit = {
    val isLoaded = loadedLibs.map(str => str contains "opencv").reduce((x, y) => x || y)
    if(!isLoaded) {
      try {
        println("hey there dude")
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
        println("ksdfjsdkfh")
      } catch {
        case e: UnsatisfiedLinkError =>
          println("Loading Library OPENCV")
          System.loadLibrary("opencv_java345")
        //      e.printStackTrace()
      }
    }
  }

  loadOpenCVOnDemand()

}

我收到的错误是:java.lang.UnsatisfiedLinkError: org.opencv.videoio.VideoCapture.VideoCapture_1(Ljava/lang/String;)J 我知道这是因为系统.loadLibrary(Core.NATIVE_LIBRARY_NAME) 无法正常工作,但我怎样才能让它工作或者我应该在哪里设置它以便应用程序正确加载库?

最佳答案

Native library support in development mode(play run) #2212将问题标识为:

When libopencv_java is loaded from the play-sbt-plugin managed code, it is loaded into the ReloadableClassLoader, but opencv-*.jar is already in the PlayDependencyClassLoader. It seems JDK does not like that kind of split. So, native library and it's java counterpart should (must?) be in the same class loader. One solution is to move out load / loadLibrary calls from the Play based project into a separate jar and then add that jar as a project dependency.

解决方法是尝试导入 play-native-loader

libraryDependencies += "com.typesafe.play" %% "play-native-loader" % "1.0.0"

并使用 NativeLoader.load 而不是像这样的 System.loadLibrary 加载库

NativeLoader.load(Core.NATIVE_LIBRARY_NAME)

play-opencv-native-example是一个工作示例。

关于scala - 不满意链接错误 : How to load native library of opencv when running play application?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55520731/

相关文章:

scala - 获得没有 future 的 Scala promise 的结果

opencv - IP 摄像机的 URL 视频流

python - 对点分布进行分类以进行对象识别

heroku - 在 heroku 上部署 play20 应用程序 (v. 2.0.2)

scala - 在 sbt 和 Scala play 框架之间共享源代码/库

scala - jackson-module-scala (play) : registerModule(DefaultScalaModule): found DefaultScalaModule. 类型;需要 : databind. 模块

scala - 实例化 'org.apache.spark.sql.hive.HiveSessionState'时出错:在Linux服务器上

playframework - 将类添加到 Play 2 自定义 FieldConstructor 中的输入

scala - 为 Scala 中的代码块提供隐式函数

python - 如何在cv2中在黑色背景上绘制红色形状?