Reputation: 5072
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
MyDriver.dll
for 64-bit using Visual Studio 2010 (10.0.40219.1 SP1Rel)MyDriver.dll
and 64-bit versions of the third-party DLLs and resource folder into the module folder ..\main\lib\win-x86_64\
modules
foldermodule.xml
MyModule.jar
.
MyDriverLoader
which loads MyDriver.dll
.sun.jdk
which I am not 100% certain is needed for JNI.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:
{JBOSS_HOME}\modules\com\mymodule\main\lib\win-x86_64
to Windows environment variable PATH
and confirmed this with echo %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;
.MSVCP100D.DLL
, MSVCR100D.DLL
and IESHIMS.DLL
are not found. I have found both MSCV*.DLL
files in both c:\Windows\System32
and C:\Windows\SysWOW64
folders, but they are different file sizes in each. Dependency Walker has detected the paths of other files to reside in system32
, so I do not understand why it isn't finding the MSCV*.DLL
files. To test, I threw them into the same folder ...\lib\win-x86_64
as MyDriver.dll
, but this changed nothing.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
- 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
Upvotes: 0
Views: 1641
Reputation: 5072
I figured it out, and here is how.
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.
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 future development deployables.
Upvotes: 1