【问题标题】:Java web application cannot use native library (.so)Java Web 应用程序不能使用本机库 (.so)
【发布时间】:2011-01-20 02:44:21
【问题描述】:

技术摘要:我正在开发一个部署在 GlassFish v3 上的 Java Web 服务,在 CentOS 5 上运行。

我的网络服务使用本地库 (.so) 提供的功能。本机库工作正常,但是我在正确配置环境方面运气不佳加载本机库但不受网络应用重新部署的影响,无需重新启动应用服务器。

到目前为止我所做的是:

最初我在 Web 服务代码中加载了库 (static {System.load(path/to/libabc.so)};),所有路径设置正确,并且工作正常,直到我重新部署应用程序并它抱怨该库是由另一个 ClassLoader 加载的。我发现原生库只加载一次。

为了尝试解决这个问题,我从 Web 应用程序中删除了库加载代码,创建了一个 Singleton 类,将其包装到 Lifecyle 模块中,将其部署到 GlassFish 共享库文件夹,然后配置 GlassFish 以在它运行包装器时运行它启动。这个想法是,现在所有的 Web 应用程序都可以引用它,因为它不绑定到一个特定的 Web 应用程序,而是由层次结构中更高的 ClassLoader 加载。

当 GlassFish 启动时,本机库已成功加载 ( linux> lsof | grep libabc.so )。但是,在我的 Web 服务 Java 代码中执行本机方法时,Web 服务代码失败并出现 UnsatisfiedLinkError。在我看来,Web 应用程序中的代码无法访问启动时加载的库。

谁能告诉我我做错了什么?

提前致谢。

【问题讨论】:

    标签: glassfish java-native-interface loadlibrary


    【解决方案1】:

    关于“生命周期模块”我不能说太多(我不知道它们是否应该对部署到 GlassFish 的应用程序“可见”)但是......

    我确实会将 JNI 库和调用 System.loadLibrary(String) 的类(例如单例)放在 webapp 之外,并将此代码部署在 domain/libdomain/lib/applibs 中(有关更多信息,请参阅 File Layout in V3this thread他们的背景)。

    这应该使代码对您的应用程序可见并且您的应用程序可以抵抗重新部署。

    【讨论】:

    • 帕斯卡,感谢您的回复。我没有使用 Lifecyle 模块,而是将 Singleton 类放在 /domain/lib 的 jar 中。在 webapp 中,我像这样动态加载类: Class> c = Class.forName("com.name.utils.SingletonClass", true, this.getClass().getClassLoader()); .. .. 然后我部署: asadmin deploy –libraries MyLib.jar /path/to/web_app.war 。当我运行 web 应用程序时,本地库加载成功,但我仍然得到 UnsatisfiedLinkError。这看起来像 ClassLoader 问题吗?
    • @water-sparks .so 在哪里?在单身人士旁边的罐子里?作为旁注,您不需要动态加载类(但这不是根本原因,UnsatisfiedLinkError 表示未找到本机库)。
    • 不,.so 在 /usr/local/lib 中。顺便说一句,如果我不动态加载类,.so 是如何加载的?
    • @water-sparks 哦,我没有注意到您使用的是System.load,它确实将完整路径作为参数,我以为您使用的是System.loadLibrary,它更便携但需要本机库路径(在 LD_LIBRARY_PATH 或 -Djava.library.path 或 GlassFish 控制台中的 Configurartion > JVM Settings > Path Settings > Native Library Path Suffix 中)。关于第二部分,.so 的加载是在静态块中完成的,因此实例化一次类就足够了。
    • 我确实使用System.load,抱歉格式化。最初不知道Native Library Suffix,后来添加了。目前我从同样使用本机方法的同一个 webapp 动态实例化 Singleton(加载 .so)。鉴于库加载类位于/domain/lib 中,我应该从哪里实例化它,以便 webapp 可以使用本机库?干杯
    【解决方案2】:

    解决了!

    最后,我把这些碎片拼在一起。

    缺少的部分 将 JNI 库(例如 jni_wrapper_for_libabc.jar)添加到 GF 共享文件夹 domains/domain1/lib 并且它工作。原生库由生命周期模块中的单例类加载,在 GF 启动时调用。

    非常感谢帕斯卡,帮了大忙!!

    干杯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 2013-04-29
      • 1970-01-01
      相关资源
      最近更新 更多