有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JAVAlang.UnsatisfiedLinkError本机库在Tomcat8中重新加载应用程序期间已加载到另一个类加载器中

我有一个Java Web应用程序在Tomcat8中运行。 我将本机库存储在Tomcat安装的/bin文件夹中

我使用JNA加载库

Native.loadLibrary("myLib",MyLib.class);

如果我必须更新或重新加载它工作的应用程序,那么它可以毫无问题地工作

我的问题是有自己的本机库的第三方库。 我将其存储在同一个/bin目录中,并且可以正常工作,但当我重新加载应用程序时,Tomcat无法加载,出现以下错误:

java.lang.UnsatisfiedLinkError: Native Library ...already loaded in another classloader

如果我重新启动tomcat服务,它会再次工作。我只是在重新加载应用程序时才发现这个问题

反编译第三方库时,我发现它的本机库加载了以下命令:

System.loadLibrary("thirdpartylib");

在应用程序重新加载的情况下,如何在tomcat级别强制加载此库而不会出现不满意的链接错误


共 (2) 个答案

  1. # 1 楼答案

    这可能不是一个真正的答案,但它太长了,无法发表评论

    你读过about Tomcat classloader problems吗?这似乎正符合你的问题

    如果这不能解决问题。。。您不知道(或不说)其他类加载器已经加载了本机库的内容。这是Tomcat模块中的设置吗?如果是,您可以禁用它吗

    由于第三方希望加载自己的本机库,这将很难解决。如果你查看系统的源代码。loadLibrary():

    public static void loadLibrary(String libname) {
        Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
    }
    

    您可以看到,它将使用调用类的类加载器,在本例中,它是第三方库的类。因此,要解决这个问题,需要将第三方库的类加载器与尝试首先加载本机库的类加载器对齐。您可以尝试enabling class loading trace并查找第三方类何时加载,然后从那里返回以查找类加载程序

  2. # 2 楼答案

    试着把你的myLib换成另一个名字,例如myLib_2,以避免冲突

    如果是同一个共享库,请尝试以下方法:

    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.

    见:https://stackoverflow.com/a/37213179/8034839