UnsatisfiedLinkError:运行播放应用程序时如何加载opencv的本机库?

时间:2019-04-04 16:18:19

标签: scala opencv playframework sbt

我正在使用带有scala的opencv运行一个play框架应用程序。当我运行该应用程序时,我从VideoCapture收到一个 UnsatisfiedLinkError ,因此如何正确加载opencv库?

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

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

我还尝试将库加载到我拥有的其他控制器以及使用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)无法正常工作,但如何使它工作或应在哪里设置以便应用程序正确加载库?

1 个答案:

答案 0 :(得分:1)

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

  

从play-sbt-plugin托管代码加载libopencv_java时,   它被加载到ReloadableClassLoader中,但是opencv-*。jar是   已经在PlayDependencyClassLoader中。看来JDK不喜欢   这种分裂。因此,本地库及其对应的Java应该(必须?)位于   同一类加载器。一种解决方案是移出负载/ loadLibrary   从基于Play的项目中调用到一个单独的jar中,然后添加   该jar作为项目依赖项。

要解决此问题,请尝试导入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是一个有效的示例。