我正在使用带有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)无法正常工作,但如何使它工作或应在哪里设置以便应用程序正确加载库?
答案 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是一个有效的示例。