Why is this JNI-based JBoss module throwing Error “Can't find dependent libraries”?

百般思念 提交于 2019-12-23 05:37:37

问题


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

  • 32-bit Windows Server 2003
  • JBoss 6.X
  • Java 1.6.X

New Environment Build

  • 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

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

  • 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 loads MyDriver.dll.
    • with a reference to module sun.jdk which I am not 100% certain is needed for JNI.

The DLL is compiled with

  • Use of MFC: Use Standard Windows Libraries

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

  1. JBoss can detect the correct DLL from the module and therefore I've configured the module correctly.
  2. Some dependent library is not in the path of JBoss.

I have tried the following solutions, but none of them worked and the Error persists:

  1. I have installed Visual Studio 2010 Redistributable x64, which was probably already packaged in anyway.
  2. I have explicitly added {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;.
  3. I've run x64 Dependency Walker, which tells me 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

回答1:


I figured it out, and here is how.

  1. 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.

  2. 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.

  3. 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.

  4. 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.



来源:https://stackoverflow.com/questions/25068381/why-is-this-jni-based-jboss-module-throwing-error-cant-find-dependent-librarie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!