【问题标题】:Shared native library in Tomcat UnsatisfiedLinkErrorTomcat UnsatisfiedLinkError 中的共享本机库
【发布时间】:2013-06-12 19:35:09
【问题描述】:

我需要在 Tomcat 中加载一个本地库,该库将被 Web 应用程序使用。我创建了一个调用 System.load("path/to/library") 的包装类,如下所述: http://wiki.apache.org/tomcat/HowTo#I.27m_encountering_classloader_problems_when_using_JNI_under_Tomcat

我的类定义与链接中的类似:

public class FooWrapper {
    public native void doFoo();
}

我可以从独立应用程序调用 doFoo()(这意味着用 C 编写的本地方法 Java_packagename_FooWrapper_doFoo(...) 已正确导出)。 但是,当我从 Web 应用程序调用 doFoo 方法时,我得到:

java.lang.UnsatisfiedLinkError: packagename.FooWrapper.doFoo()V

我可以使用此处描述的技巧获取 ClassLoader 加载的本机库列表:How do I get a list of JNI libraries which are loaded?

   java.lang.reflect.Field loadedLibraries = ClassLoader.class.getDeclaredField("loadedLibraryNames");
   loadedLibraries.setAccessible(true);
   final Vector<String> libraries = (Vector<String>) loadedLibraries.get(ClassLoader.getSystemClassLoader());

并且我的本机库列在库向量中,因此调用 System.load(...) 的静态块将毫无例外地执行。但是,当我从 Web 应用程序调用 doFoo() 时,Java 似乎无法在本机库中找到合适的函数。我错过了什么?

【问题讨论】:

    标签: tomcat java-native-interface classloader


    【解决方案1】:

    您错过了问题不是加载库,这是您的大部分问题都致力于解决的问题:它是方法签名。它与加载的库中实际存在的内容不符。自从您生成 .h 文件后,您是否更改了 Java 本机方法签名?如果是这样,请重新生成它。您的 .h 文件是否与您的 .c 或 .cpp 文件一致?您是否在 .c/.cpp 文件中包含 .h 文件?所有这些条件都是必需的。

    【讨论】:

    • 您好 EJP,谢谢您的回答,我没有关注方法签名,因为正如我所说,它在独立应用程序中工作正常(即在主方法中,加载库并调用本机方法运行没有问题)。我已经使用 javah 工具生成了标头并实现了方法。本机库已正确编译。 UnsatisfiedLinkError 错误仅在 tomcat 上下文中显示。
    • 因此,您正在 Tomcat 上下文中加载旧版本的库。
    猜你喜欢
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多