为什么这个基于 JNI 的 JBoss 模块会抛出错误"找不到依赖库"?
Why is this JNI-based JBoss module throwing Error "Can't find dependent libraries"?
我有一个Java web应用程序myproject.war
部署到JBoss。应用程序的一部分使用JNI连接到c++ DLL,该DLL从一组第三方库调用函数。我们正在将这个应用程序从x32服务器迁移到x64服务器。
优先环境构建
- 32位Windows Server 2003
- JBoss 6。X Java 1.6.X
新建环境
- 64位Windows Server 2008 R2, SP1 (6.1.7601) JBoss AS 7.2.0 Final "Janus"
- Java Runtime 1.7.0_45-b18. Visual Studio 2010 Redistributable x64已安装
在旧系统上,自定义DLL和第三方库被随意地转储到C:WindowsSystem32
中,并且应用程序能够通过JNI成功地连接到它们。第三方库包括几个dll、一些ICC配置文件和一个Resource文件夹,其中包含包含True-type字体、配置和其他文件的子文件夹。
对于迁移,创建了一个JBoss模块来包含JNI代码。将Java/JNI代码移至MyModule.jar
,将MyDriver.dll
重新编译为x64。获取X64版本的第三方库。
我有
- 使用Visual Studio 2010 (10.0.40219.1 SP1Rel)重新编译64位
MyDriver.dll
- 将
MyDriver.dll
和64位版本的第三方dll和资源文件夹放入模块文件夹..mainlibwin-x86_64
- 将模块文件复制到
modules
文件夹 下的路径 -
module.xml
创建- 与适当的资源
MyModule.jar
。- 类
MyDriverLoader
加载MyDriver.dll
。
- 类
- 参考模块
sun.jdk
,我不是100%确定JNI需要。
- 与适当的资源
使用
编译DLL- MFC的使用:使用标准Windows库
无论我做什么,在启动应用程序时,JBoss都会抛出以下Java错误:
. lang。UnsatisfiedLinkError: D:Jboss Jboss -7.2.0. final modulescommymodulemainlibwin-x86_64MyDriver.dll: Can't find dependent libraries
这告诉我的是
- JBoss可以从模块中检测正确的DLL,因此我已经正确配置了模块。
- 某个依赖库不在JBoss的路径中。
我尝试了以下解决方案,但都不起作用,错误仍然存在:
- 我已经安装了Visual Studio 2010 Redistributable x64,它可能已经打包在里面了。
- 我已经明确地将
{JBOSS_HOME}modulescommymodulemainlibwin-x86_64
添加到Windows环境变量PATH
中,并与echo %PATH%
确认这一点,其中包括:D:Javajdk1.7.0_45bin;D:Jbossjboss-7.2.0.Finalmodulescommymodulemainlibwin-x86_64;
。 - 我已经运行了x64 Dependency Walker,它告诉我没有找到
MSVCP100D.DLL
,MSVCR100D.DLL
和IESHIMS.DLL
。我在c:WindowsSystem32
和C:WindowsSysWOW64
文件夹中都找到了MSCV*.DLL
文件,但是它们的文件大小不同。依赖沃克已经检测到其他文件的路径驻留在system32
,所以我不明白为什么它没有找到MSCV*.DLL
文件。为了测试,我将它们放入与MyDriver.dll
相同的文件夹...libwin-x86_64
中,但这没有改变任何东西。
我能做些什么来解决这个问题?
module.xml
<module xmlns="urn:jboss:module:1.1" name="com.mymodule">
<main-class name="com.mymodule.DriverClassName"/>
<resources>
<resource-root path="MyModule.jar"/>
</resources>
<dependencies>
<module name="sun.jdk"/>
</dependencies>
</module>
MyDriverLoader.java
public class MyDriverLoader {
/**
* Load C++ Library
*/
static {
System.loadLibrary("MyDriver");
}
/**
* Native Method to return the version of the C++ DLL.
*/
public native static String getVersion();
/**
* Main method calls getVersion.
*
* @param args
*/
public static void main(String args[]) {
System.out.println("MyDriverLoader calling MyDriver.dll version " + getVersion());
}
}
jboss-deployment-structure
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="com.mymodule" />
</dependencies>
</deployment>
</jboss-deployment-structure>
模块mymodule
的文件夹结构
{JBOSS_HOME} com mymodule里 模块主要
- MyModule.jar
- 包含
- lib win-x86_64
- MyDriver.dll
- ThirdPartyA.dll
- ThirdPartyB.dll
- ThirdPartyC.dll
- ThirdPartyD.dll
- 环境 数据资源
- foo.optionfile
- bar.optionfile
我想出来了,方法如下。
-
我首先将DLL从JBoss中取出,并尝试通过x64 dev/qa服务器上的JNI调用本机方法直接访问它。这失败了,出现了同样的错误。
-
我从DLL中剥离了对第三方库的引用,并试图再次访问它。这也以同样的错误失败了。这意味着不是第三方库或它们的路径问题。
-
我创建了一个普通的DLL,它什么也不做,只是吐出一个字符串,并试图以与前两次相同的方式访问它。它也失败了。
-
我一直在编译vs2010中的DLL作为调试。我将DLL重新编译为Release。
我找到了一个很有帮助的答案,我再也找不到了,否则我会把它链接起来。
正如我现在所理解的,如果你在调试中编译一个DLL,它不应该是可重新分发的。我在Debug中编译并在x32开发服务器上使用的x32 DLL不是这种情况,但编译后的x64 DLL肯定是这种情况。我将其编译为Release,并能够在整个应用程序中使用DLL。
我已经更改了构建未来开发可部署的例程。
- 分段错误当我试图运行程序时出错
- .h 和.cpp文件分离时出错,但仅使用 .h 文件时没有错误.我做错了什么?
- 创建 OpenCV 非自由版本 v4.3 时出错,可折叠.cpp错误 C2039、2605
- 制作时出错,C++"db.c:2127:错误:在"||"标记之前应使用";"
- C++语法错误,编译器不会警告或 int v = func(&v) 出错;
- 在VS2015中访问类成员时运行时错误,但在Linux上未访问时出错
- 如何更改路径以修复错误"./main:加载共享库 libmkl_core.so 时出错?
- 为什么在定义类之前声明类的对象会在友元类中给出错误,而在友元函数中不会出错
- 安装 mply 库时出错.致命错误:gsl/gsl_sf.h:没有这样的文件或目录
- Rcpp/C++/R:比较日期时间矢量与日期时间时出错(错误:"运算符>"的不明确重载)
- 编译特征程序时出错:错误:'seq'不是'Eigen'的成员
- 可能的 GCC 链接器错误会导致将弱符号和局部符号链接在一起时出错
- 非标准语法;使用 '&' 创建指向成员的指针错误,将成员函数分配给向量时出错
- 为 freebsd 11 编译 gcc4.8.5 时出错: 错误: 未知类型名称 'choke'
- 运算符重载时出错(错误:"运算符<<不匹配(操作数类型为"std::basic_ostream<char>"和"const char [2]")
- 我同时使用了莱布尼茨和瓦利斯公式来估算π但输出数字错误,我不知道我哪里出错了
- 显示错误消息框时出错.我该如何显示它
- 使用 swig 时出错:输入 (1) 中的语法错误
- 编译类 C++ 中的线程时出错(错误 xthread)
- 在 Visual Studio 2015 社区中消除错误时出错