我尝试将OpenCV安装为JBoss-as实例的全局模块。版本是:
我从全新安装的Ubuntu Server 12.04 64位开始,只安装了JBoss-as和OpenCV。
OpenCV java包装器使用JNI调用。因此需要做两件事:
可在/usr/share/OpenCV/java/
中找到(关于安装)
我也指出了一些观察:
opencv-245.jar
在pom.xml
中列为依赖项,因此打包到war
)< / LI>
醇>
只要我将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.so
和lib/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点中描述的过程也不起作用并给出相同的例外情况如上。也许这些信息可以提供帮助。
有人有指针或解决方案吗?
答案 0 :(得分:6)
我终于解决了问题并在这里写下了帮助其他人的答案。
问题不在libopencv_java245.so
的路径中,而是在JBoss类加载器中。
对于Preamble第3点(有效)中描述的情况,加载war
文件的ClassLoader与加载opencv-245.jar
(嵌入war
)中的相同,并且我的代码中对System.loadLibrary("opencv_java245")
的调用对同一个ClassLoader有影响,因为它已经加载了包含此方法调用的Class。所有这些都对同一个ClassLoader有影响,一切正常。
现在为什么它没有使用ear
跟进的原因是ear
有自己的ClassLoader,然后每个子部署都是另一个。第一个ClassLoader部署ear
,其中包含opencv-245.jar
依赖项,然后另一个ClassLoader部署war
中包含的ear
。由于调用System.loadLibrary("opencv_java245")
位于war
,因此此命令的效果会对war
的ClassLoader产生影响,但opencv-245.jar
会加载到ear
中ClassLoader。因此,当尝试调用本机库时,java无法找到该链接,因为它们位于不同的ClassLoader上。
最后,这里的兴趣点是JBoss模块。在描述初始问题中配置的模块时,这是一个加载opencv-245.jar
的高级JBoss ClassLoader。 ClassLoader还将自动知道在哪里搜索本机库:$MODULE_PATH/lib/linux-x86_64/
。但问题是加载库。对System.loadLibrary("opencv_java245")
的调用必须在收费为opencv-245.jar
的同一个ClassLoader中完成。因此,无法在代码中加载这样的库:
static {
System.loadLibrary("opencv_java245");
}
因为它会影响已加载Class的ClassLoader,而不会影响JBoss的ClassLoader。解决方案是修改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。然后正确链接本机调用,因为jar
和so
这两个库都加载到同一个ClassLoader中。
答案 1 :(得分:1)
如果您使用的是OpenCV(org.openpnp软件包)3.4.2+,而不是:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
您可以使用:
OpenCV.loadLocally();
我正在使用jboss wildfly,并且在进行多个部署时遇到问题。本机类已经加载,但这解决了问题。
答案 2 :(得分:0)
将libopencv_java245.so文件添加到为OpenCV模块创建的同一目录中。然后将其添加为资源,以便将其添加到类路径中并在运行时可用。
所以你的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"/>
<resource-root path="."/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
答案 3 :(得分:0)
找到此链接,提供有关加载本机库的说明
https://docs.jboss.org/author/display/MODULES/Native+Libraries