gpt4 book ai didi

java - OpenCV 作为 JBoss——作为全局模块

转载 作者:搜寻专家 更新时间:2023-10-31 19:47:11 24 4
gpt4 key购买 nike

问题呈现

我尝试将 OpenCV 安装为 JBoss-as 实例的全局模块。版本是:

  • JBoss-as:7.1.1 Final
  • OpenCV:2.4.5(编译时支持 Java)

我从全新安装的 Ubuntu Server 12.04 64 位开始,只安装了 JBoss-as 和 OpenCV。

序言

OpenCV java 包装器使用 JNI 调用。因此需要做两件事:

  • opencv-245.jar
  • libopencv_java245.so

并且在 /usr/share/OpenCV/java/ 中可用(关于安装)

我也指出一些观察:

  1. JBoss 安装正确(应用程序可以部署并正常运行)
  2. 带有java支持的OpenCV的编译和安装是正确的(使用OpenCV的Java类正在工作)
  3. 使用 OpenCV 并使用 maven 部署在 JBoss 上的基本 Web 应用程序(opencv-245.jarpom.xml 中列为依赖项,因此打包到 war 中)

问题描述

一旦我将 OpenCV 定义为 JBoss 全局模块(在 pom.xml 中设置 <scope>provided</scope>),就会引发此异常:

java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat()J
org.opencv.core.Mat.n_Mat(Native Method)
org.opencv.core.Mat.<init>(Mat.java:441)
WS.printMessage(WS.java:15)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:616)
org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:155)
org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:257)
org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:222)
org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:211)
org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:525)
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:502)
org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:119)
org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208)
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

看来 OpenCV jar找到库是因为从中引发了异常。它也不会提示找不到某些库,例如(取自末尾的第一个链接):

java.lang.UnsatisfiedLinkError: no xxxx in java.library.path

因此我猜 libopencv_java245.so不是问题。具体配置如下。

配置

我定义了 org.opencv modules/org/opencv/main/module.xml 中的模块:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.opencv">
<resources>
<resource-root path="opencv-245.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>

然后我放入同一个文件夹opencv-245.jar还有libopencv_java245.solib/linux-x86_64/子文件夹(如 Native Library 中所述)

为了将此模块定义为全局模块,我在 standalone/configuration/standalone.xml 中进行了修改:

<subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.opencv" slot="main"/>
</global-modules>
</subsystem>

最后使用我在 src/main/webapp/WEB-INF/jboss-deployment-structure.xml 中设置的全局模块:

<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.opencv" />
</dependencies>
</deployment>
</jboss-deployment-structure>

我也提醒一下,我把<scope>provided</scope>在我的行家pom.xml .

此外,放置:

System.loadLibrary("opencv_java245");

或者不在代码中不会改变任何东西。

额外观察

我还注意到 ear应用程序,由一个 war 组成和一个jar ,即使“序言”中第 3 点中描述的过程也不起作用,并给出与上述相同的异常。也许这些信息可以提供帮助。

有人有一些指示或解决方案吗?

相关问题

最佳答案

我终于解决了这个问题并将答案写在这里以帮助其他人。

问题不在 libopencv_java245.so 的路径中,而是在 JBoss 类加载器中。

对于序言第 3 点中描述的情况(有效),加载 war 文件的类加载器与加载 opencv-245.jar 相同(这是嵌入到 war) 中,并且在我的代码中调用 System.loadLibrary("opencv_java245") 对同一个 ClassLoader 有影响,因为它已经加载了包含这个的类方法调用。所有都对同一个 ClassLoader 产生影响,并且一切正常。

现在它不能与 ear 一起工作的原因是 ear 有自己的 ClassLoader,然后每个子部署都是另一个。第一个 ClassLoader 部署 ear,其中包含 opencv-245.jar 依赖项,然后另一个 ClassLoader 部署包含在 中的 war。因为调用System.loadLibrary("opencv_java245")是在war中,所以这个命令的效果对war的ClassLoader有影响,但是 opencv-245.jar 被加载到 ear 类加载器中。因此,当尝试调用 native 库时,java 无法找到链接,因为它们位于不同的 ClassLoader 上。

最后,这里的兴趣点是 JBoss 模块。在描述我最初问题中配置的模块时,这是一个高级 JBoss ClassLoader,它加载 opencv-245.jar。 ClassLoader 也会自动知道在哪里搜索本地库:在 $MODULE_PATH/lib/linux-x86_64/ 中。但问题是加载库。对 System.loadLibrary("opencv_java245") 的调用必须在加载了 opencv-245.jar 的同一类加载器中完成。因此不可能在您的代码中像这样加载库:

static {
System.loadLibrary("opencv_java245");
}

因为它会对加载您的类的 ClassLoader 产生影响,而不会对 JBoss 产生影响。解决办法是修改opencv-245.jar,在其中添加一个org.opencv.core.Loader类,例如,它只有一个方法:

package org.opencv.core

class Loader
{
public static void loadLibrary(String name)
{
System.loadLibrary(name);
}
}

然后在你的课上你可以放:

static {
Loader.loadLibrary("opencv_java245");
}

并且 System.loadLibrary 调用被放置在 opencv-245.jar 中将产生与加载 opencv-245.jar< 相同的 ClassLoader 的效果。然后 native 调用被正确链接,因为库、jarso 都被加载到同一个 ClassLoader 中。

关于java - OpenCV 作为 JBoss——作为全局模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16173362/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com