为什么这个基于JNI的JBoss模块抛出错误“无法找到依赖库”? [英] Why is this JNI-based JBoss module throwing Error "Can't find dependent libraries"?
问题描述
我有一个部署到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 7601)
- JBoss AS 7.2.0 FinalJanus
- Java Runtime 1.7.0_45-b18。
- 安装Visual Studio 2010 Redistributable x64
- 使用Visual Studio 2010(10.0.40219.1 SP1Rel)重新编译
MyDriver.dll
以用于64位 - 放置
MyDriver .dll
和64位版本的第三方DLL和资源文件夹复制到模块文件夹.. \main\lib\win-x86_64\
- 将模块文件复制到
modules
文件夹下的路径 - 使用适当的资源
创建
。module.xml
- MyModule.jar
- 其中有
MyDriverLoader
类,它加载MyDriver.dll
。sun.jdk
的引用
- 使用MFC:使用标准Windows库
- JBoss可以从模块中检测到正确的DLL
- 我安装了Visual Studio 2010
- 我已经明确添加了
{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\我已经运行了x64 Dependency Walker,它告诉我
MSVCP100D.DLL
/ code>, - 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
-
我首先将DLL从JBoss中取出,并试图直接通过调用本地方法访问它JNI在x64 dev / qa服务器上。这失败与相同的错误。 这意味着它不是JBoss。
-
我从DLL中删除了对第三方库的引用,并尝试再次访问。这也失败了相同的错误。 这意味着它不是第三方库或其中的路径问题。
-
但吐出一个字符串,并尝试访问它的方式与前两次相同的方式。它也失败了。 这意味着它不是我的代码。
- 我在VS 2010中编译DLL为Debug。我将DLL重新编译为Release。 这解决了这个问题。
- 32-bit Windows Server 2003
- JBoss 6.X
- Java 1.6.X
- 64-bit 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 installed
- recompiled
MyDriver.dll
for 64-bit using Visual Studio 2010 (10.0.40219.1 SP1Rel) - placed
MyDriver.dll
and 64-bit versions of the third-party DLLs and resource folder into the module folder..\main\lib\win-x86_64\
- copied the module files to a path under the
modules
folder - created
module.xml
- with the appropriate resource
MyModule.jar
.- which has class
MyDriverLoader
which loadsMyDriver.dll
.
- which has class
- with a reference to module
sun.jdk
which I am not 100% certain is needed for JNI.
- with the appropriate resource
- Use of MFC: Use Standard Windows Libraries
- JBoss can detect the correct DLL from the module and therefore I've configured the module correctly.
- Some dependent library is not in the path of JBoss.
- I have installed Visual Studio 2010 Redistributable x64, which was probably already packaged in anyway.
- I have explicitly added
{JBOSS_HOME}\modules\com\mymodule\main\lib\win-x86_64
to Windows environment variablePATH
and confirmed this withecho %PATH%
which includes:D:\Java\jdk1.7.0_45\bin;D:\Jboss\jboss-7.2.0.Final\modules\com\mymodule\main\lib\win-x86_64;
. - I've run x64 Dependency Walker, which tells me
MSVCP100D.DLL
,MSVCR100D.DLL
andIESHIMS.DLL
are not found. I have found bothMSCV*.DLL
files in bothc:\Windows\System32
andC:\Windows\SysWOW64
folders, but they are different file sizes in each. Dependency Walker has detected the paths of other files to reside insystem32
, so I do not understand why it isn't finding theMSCV*.DLL
files. To test, I threw them into the same folder...\lib\win-x86_64
asMyDriver.dll
, but this changed nothing. - 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
I first took the DLL out of JBoss and tried to access it directly from a call to a native method via JNI on the x64 dev/qa server. This failed with the same error. This meant it was not JBoss.
I stripped references to the third-party libraries from the DLL and tried to access it again. This also failed with the same error. This meant it was not the third-party libraries or a path issue with them.
I created a plain DLL which did nothing but spit out a string and tried to access it in the same way as the prior two times. It also failed. This meant it was not my code.
I had been compiling the DLL in VS 2010 as Debug. I recompiled the DLL as Release. This solved the issue.
新建环境构建
在旧系统上,自定义DLL和第三方库毫无意义地转储到
C:\Windows \System32\
,应用程序能够通过JNI成功连接到它们。第三方库包括几个DLL,一些ICC配置文件和一个资源文件夹,其中包含True类型字体,配置和其他文件的子文件夹。 迁移,一个JBoss模块被创建为包含JNI代码。将Java / JNI代码移动到 MyModule.jar
,并将 MyDriver.dll
重新编译为x64。
我有
这个DLL是用
否无论我做什么,当启动应用程序时,JBoss抛出以下Java错误:
java.lang.UnsatisfiedLinkError:D:\Jboss \jboss-7.2.0.Final \modules\com\mymodule\main\lib\win-x86_64\MyDriver.dll:找不到相关库
这告诉我的是
$ b
我试过下面的解决方案,但没有一个工作,并且错误仍然存在:
未找到MSVCR100D.DLL
和 IESHIMS.DLL
。我在 c:\Windows \System32
和<$ c $中都找到了 MSCV * .DLL
c> C:\Windows \SysWOW64 文件夹,但它们在每个文件大小不同。依赖Walker已经检测到其他文件驻留在 system32
的路径,所以我不明白为什么它找不到 MSCV * .DLL
文件。要测试,我把他们放到同一个文件夹 ... \lib \win-x86_64
作为 MyDriver.dll
$ b
module.xml
< module xmlns =urn:jboss:module:1.1name =com.mymodule>
< main-class name =com.mymodule.DriverClassName/>
< resources>
< resource-root path =MyModule.jar/>
< / resources>
< dependencies>
< module name =sun.jdk/>
< / dependencies>
< / module>
MyDriverLoader.java
strong>
public class MyDriverLoader {
/ **
* Load C ++ Library
* /
static {
System.loadLibrary(MyDriver);
}
/ **
*返回C ++ DLL版本的Native方法。
* /
public native static String getVersion();
/ **
*主方法调用getVersion。
*
* @param args
* /
public static void main(String args []){
System.out.println(MyDriverLoader调用MyDriver.dll版本+ getVersion());
}
}
jboss-部署结构
< jboss-deployment-structure&
< deployment>
< dependencies>
< module name =com.mymodule/>
< / dependencies>
< / deployment>
< / jboss-deployment-structure>
模块的文件夹结构 mymodule
:
{JBOSS_HOME} \modules\com\mymodule\main
是如何。
我发现一个SO答案,
我现在明白了,如果你在Debug中编译一个DLL,它不应该是可重新分发的。在我在Debug中编译并在我的x32开发服务器上使用的x32 DLL中并不是这样,但是对于编译的x64 DLL肯定是这样。我编译为Release,并且能够在我的应用程序中使用DLL。我改变了构建开发可部署的例程。
I have a Java web application myproject.war
deployed to JBoss. A portion of the application uses JNI to connect to a C++ DLL, which calls functions from a set of third-party libraries. We are migrating this application from a x32 server to a x64 server.
Prior Environment Build
New Environment Build
On the old system, the custom DLL and third-party libraries were unceremoniously dumped into C:\Windows\System32\
and the application was able to successfully connect to them via JNI. The third-party libraries include several DLLs, some ICC Profiles, and a Resource folder with sub-folders of files including True-type fonts, configurations and other files.
For the migration, a JBoss module was created to contain the JNI code. The Java / JNI code was moved to MyModule.jar
, and MyDriver.dll
was recompiled to x64. x64 versions of the third-party libraries were obtained.
I have
The DLL is compiled with
No matter what I do, when starting the application, JBoss throws the following Java Error:
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
What this tells me is
I have tried the following solutions, but none of them worked and the Error persists:
What can I do to resolve this?
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>
folder structure of module mymodule
:
{JBOSS_HOME}\modules\com\mymodule\main
I figured it out, and here is how.
I found a SO answer that helped that I cannot find again, otherwise I would link it.
As I now understand it, if you compile a DLL in Debug, it should not be redistributable. This was not the case with the x32 DLLs that I compiled in Debug and used on my x32 development servers, but was certainly the case with the complied x64 DLL. I compiled as Release and was able to use the DLL throughout my application. I have changed the routine for building a development deployable.
这篇关于为什么这个基于JNI的JBoss模块抛出错误“无法找到依赖库”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!