UnsatisfiedLinkError: How to load native library of opencv when running play application?
UnsatisfiedLinkError: How to load native library of opencv when running play application?
我正在 运行使用 opencv 和 scala 开发一个游戏框架应用程序。当我 运行 应用程序收到来自 VideoCapture 的 UnsatisfiedLinkError 时,我该如何正确加载 opencv 库?
当我 运行 使用来自 opencv 的 classes 进行测试时,一切正常。我总是设置 System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 并正确定义 java.path.library 参数。但是当我 运行 播放应用程序时,这与测试不一样。
在其他帖子中,人们一直在使用 play 中的抽象 GlobalSetting class 解决此问题,并在 beforeStart() 方法中加载库。但这已被弃用,现在 Play 建议进行热切绑定。当我启动服务器时,我已经尝试首先为 运行 创建一个 Eager 加载程序,我以与 运行 测试相同的方式加载库。 class 运行 中的代码首先是它应该是的,但它并没有解决我的问题。
我还尝试在我拥有的不同控制器和 class 中加载库,我在其中使用 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 和我知道这是因为 System.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 是一个工作示例。
我正在 运行使用 opencv 和 scala 开发一个游戏框架应用程序。当我 运行 应用程序收到来自 VideoCapture 的 UnsatisfiedLinkError 时,我该如何正确加载 opencv 库?
当我 运行 使用来自 opencv 的 classes 进行测试时,一切正常。我总是设置 System.loadLibrary(Core.NATIVE_LIBRARY_NAME) 并正确定义 java.path.library 参数。但是当我 运行 播放应用程序时,这与测试不一样。
在其他帖子中,人们一直在使用 play 中的抽象 GlobalSetting class 解决此问题,并在 beforeStart() 方法中加载库。但这已被弃用,现在 Play 建议进行热切绑定。当我启动服务器时,我已经尝试首先为 运行 创建一个 Eager 加载程序,我以与 运行 测试相同的方式加载库。 class 运行 中的代码首先是它应该是的,但它并没有解决我的问题。
我还尝试在我拥有的不同控制器和 class 中加载库,我在其中使用 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 和我知道这是因为 System.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 是一个工作示例。