技术摘要:我正在开发部署在GlassFish v3上的Java Web服务,在CentOS 5上运行。
我的Web服务使用本机库(.so)提供的功能。本机库工作正常,但我没有太多运气正确配置环境加载本机库但不受Web应用重新部署的影响,而无需重新启动应用服务器。
到目前为止我所做的是:
最初我在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应用程序中的代码无法访问启动时加载的库。
谁能告诉我我做错了什么?
提前致谢。
答案 0 :(得分:4)
我不能多说“Lifecyle模块”(我不知道它们是否应该对部署到GlassFish的应用程序“可见”)但是......
我确实会将JNI库和调用System.loadLibrary(String)
的类(例如单个代码)放在webapp之外,并在domain/lib
或domain/lib/applibs
中部署此代码(请参阅{{3 }和File Layout in V3了解更多背景信息)。
这应该使您的应用程序可以看到代码,并且您的应用程序可以抵抗重新部署。
答案 1 :(得分:2)
最后,我把各个部分放在一起。
缺失部分将JNI库(例如jni_wrapper_for_libabc.jar
)添加到GF共享文件夹domains/domain1/lib
并且它有效。本机库由生命周期模块中的Singleton类加载,该模块在GF启动时调用。
非常感谢Pascal,很棒的帮助伙伴!!
干杯