java.lang.UnsatisfiedLinkError:Native Library XXX.so已经加载到另一个类加载器中 [英] java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader

查看:142
本文介绍了java.lang.UnsatisfiedLinkError:Native Library XXX.so已经加载到另一个类加载器中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经部署了一个Web应用程序,其中包含以下代码。

I have deployed one web-application, which contains following code.

System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);

现在,我部署了另一个也有相同代码的网络应用程序。当它试图加载库时,它会抛出以下错误。

Now, I deployed another web-application which also have same code. When it tries to load library, it throwing following error.

Exception in thread "Thread-143" java.lang.UnsatisfiedLinkError: 
Native Library /usr/lib/jni/libopencv_java248.so already loaded in
another classloader

我想同时运行这两个应用程序。

I want to run these both application simultaneously.

到现在为止我尝试过:


  1. 在一个应用程序中加载库并将上述异常捕获到另一个应用程序中

  2. 从两个应用程序中删除jar并将opencv.jar放入Tomcat的类路径中(即在/ usr / share中) / tomcat7 / lib)。

但以上都没有,我可以做任何建议吗?

But none of above worked, any suggestions by which I can do this ?

编辑

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

此行有效但在我实际使用该库时会出现异常。那时我跟着

This line works but gets exception when I am actually going to use that library. That is when I do following

Mat mat = Highgui.imread("/tmp/abc.png");

我得到这个例外

java.lang.UnsatisfiedLinkError: org.opencv.highgui.Highgui.imread_1(Ljava/lang/String;)J
    at org.opencv.highgui.Highgui.imread_1(Native Method)
    at org.opencv.highgui.Highgui.imread(Highgui.java:362)


推荐答案

问题在于OpenCV如何处理本机库的初始化。

The problem is with how OpenCV handles the initialization of the native library.

通常使用本机库的类将具有加载库的静态初始化程序。这样,类和本机库将始终加载到同一个类加载器中。使用OpenCV,应用程序代码加载本机库。

Usually a class that uses a native library will have a static initializer that loads the library. This way the class and the native library will always be loaded in the same class loader. With OpenCV the application code loads the native library.

现在存在一个限制,即只能在一个类加载器中加载本机库。 Web应用程序使用自己的类加载器,因此如果一个Web应用程序加载了本机库,则另一个Web应用程序不能执行相同操作。因此,加载本机库的代码不能放在webapp目录中,但必须放在容器的(Tomcat)共享目录中。如果您使用上面的常规模式编写了一个类(在使用类的静态初始化程序中 loadLibrary ),那么将包含该类的jar放在共享目录中就足够了。但是,使用OpenCV和Web应用程序代码中的 loadLibrary 调用,本机库仍将加载到错误的类加载器中,您将获得 UnsatisfiedLinkError

Now there's the restriction that a native library can only be loaded in one class loader. Web applications use their own class loader so if one web application has loaded a native library, another web application cannot do the same. Therefore code loading native libraries cannot be put in a webapp directory but must be put in the container's (Tomcat) shared directory. When you have a class written with the usual pattern above (loadLibrary in static initializer of using class) it's enough to put the jar containing the class in the shared directory. With OpenCV and the loadLibrary call in the web application code however, the native library will still be loaded in the "wrong" class loader and you will get the UnsatisfiedLinkError.

要使正确的类加载器加载本机库,您可以使用单个静态方法创建一个小类 loadLibrary 。将此类放在一个额外的jar中,并将此jar放在共享的Tomcat目录中。然后在Web应用程序中,通过调用新的静态方法替换对 System.loadLibrary 的调用。这样,OpenCV类的类加载器及其本机库将匹配,并且可以初始化本机方法。

To make the "right" class loader load the native library you could create a tiny class with a single static method doing only the loadLibrary. Put this class in an extra jar and put this jar in the shared Tomcat directory. Then in the web applications replace the call to System.loadLibrary with a call to your new static method. This way the class loaders for the OpenCV classes and their native library will match and the native methods can be initialized.

编辑:示例按评论者的要求

example as requested by a commenter

而不是

public class WebApplicationClass {
    static {
        System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
    }
}

使用

public class ToolClassInSeparateJarInSharedDirectory {
    public static void loadNativeLibrary() {
        System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
    }
}

public class WebApplicationClass {
    static {
        ToolClassInSeparateJarInSharedDirectory.loadNativeLibrary();
    }
}

这篇关于java.lang.UnsatisfiedLinkError:Native Library XXX.so已经加载到另一个类加载器中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆