gpt4 book ai didi

java - 为什么这个基于 JNI 的 JBoss 模块抛出 Error "Can' t find dependent libraries”?

转载 作者:行者123 更新时间:2023-11-28 06:45:36 25 4
gpt4 key购买 nike

我有一个部署到 JBoss 的 Java Web 应用程序 myproject.war。应用程序的一部分使用 JNI 连接到 C++ 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 运行时 1.7.0_45-b18。
  • 已安装 Visual Studio 2010 Redistributable x64

在旧系统上,自定义 DLL 和第三方库被毫不客气地转储到 C:\Windows\System32\ 中,应用程序能够通过 JNI 成功连接到它们。第三方库包括几个 DLL、一些 ICC 配置文件和一个 Resource 文件夹,其中包含文件的子文件夹,包括 True-type 字体、配置和其他文件。

为了迁移,创建了一个 JBoss 模块来包含 JNI 代码。 Java/JNI 代码被移动到 MyModule.jarMyDriver.dll 被重新编译为 x64。已获取x64版本的第三方库。

我有

  • 使用 Visual Studio 2010 (10.0.40219.1 SP1Rel) 为 64 位重新编译 MyDriver.dll
  • MyDriver.dll 和 64 位版本的第三方 DLL 和资源文件夹放入模块文件夹 ..\main\lib\win-x86_64\
  • 将模块文件复制到modules 文件夹下的路径
  • 创建了module.xml
    • 使用适当的资源 MyModule.jar
      • 具有加载 MyDriver.dll 的类 MyDriverLoader
    • 引用模块 sun.jdk,我不是 100% 确定 JNI 需要它。

DLL是用

编译的
  • MFC 的使用:使用标准 Windows 库

无论我做什么,启动应用程序时,JBoss 都会抛出以下 Java 错误:

java.lang.UnsatisfiedLinkError: D:\Jboss\jboss-7.2.0.Final\modules\com\mymodule\main\lib\win-x86_64\MyDriver.dll: Can't find dependent libraries

这告诉我的是

  1. JBoss 可以从模块中检测到正确的 DLL,因此我已经正确配置了模块。
  2. 某些依赖库不在JBoss的路径中。

我已经尝试了以下解决方案,但都没有奏效并且错误仍然存​​在:

  1. 我已经安装了 Visual Studio 2010 Redistributable x64,它可能已经打包好了。
  2. 我已将 {JBOSS_HOME}\modules\com\mymodule\main\lib\win-x86_64 显式添加到 Windows 环境变量 PATH 并使用 确认echo %PATH% 其中包括:D:\Java\jdk1.7.0_45\bin;D:\Jboss\jboss-7.2.0.Final\modules\com\mymodule\main\lib\win -x86_64;.
  3. 我运行了 x64 Dependency Walker,它告诉我未找到 MSVCP100D.DLLMSVCR100D.DLLIESHIMS.DLL。我在 c:\Windows\System32C:\Windows\SysWOW64 文件夹中都找到了 MSCV*.DLL 文件,但它们是每个文件大小不同。 Dependency Walker 已检测到其他文件的路径驻留在 system32 中,所以我不明白为什么它找不到 MSCV*.DLL 文件。为了测试,我将它们放入与 MyDriver.dll 相同的文件夹 ...\lib\win-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}\modules\com\mymodule\main

  • MyModule.jar
    • module.xml
    • \lib\win-x86_64\
    • MyDriver.dll
    • ThirdPartyA.dll
    • ThirdPartyB.dll
    • ThirdPartyC.dll
    • ThirdPartyD.dll
    • \Resource\Data\Settings\
      • foo.optionfile
      • bar.optionfile

最佳答案

我想通了,下面是方法。

  1. 我首先从 JBoss 中取出 DLL,并尝试通过 x64 dev/qa 服务器上的 JNI 调用本地方法直接访问它。这失败并出现相同的错误。 这意味着它不是 JBoss。

  2. 我从 DLL 中删除了对第三方库的引用并尝试再次访问它。这也因同样的错误而失败。 这意味着它不是第三方库或它们的路径问题。

  3. 我创建了一个纯 DLL,它只输出一个字符串并尝试以与前两次相同的方式访问它。它也失败了。 这意味着它不是我的代码。

  4. 我一直在 VS 2010 中将 DLL 编译为 Debug。我将 DLL 重新编译为 Release。 这解决了问题。

我找到了一个有用的 SO 答案,但我找不到了,否则我会链接它。

据我现在的理解,如果您在 Debug 中编译 DLL,它不应该是可再分发的。我在调试中编译并在我的 x32 开发服务器上使用的 x32 DLL 不是这种情况,但编译的 x64 DLL 肯定是这种情况。我编译为 Release 并且能够在我的整个应用程序中使用 DLL。

我改变了构建 future 开发部署的例程。

关于java - 为什么这个基于 JNI 的 JBoss 模块抛出 Error "Can' t find dependent libraries”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25068381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com