我正在运行一个使用 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/