1

I have problem with JNI, again...

This time my code works... But... not correct on all PC.

I have:

  1. Jar file -> my prog
  2. dll file -> with native methods
  3. another dll file -> with another functions.

On my PC all this files are in ONE folder.

Files code (.java):

// loading library
    try {
        Runtime.getRuntime().loadLibrary("E140tests");
        setText("Library E140tests.dll was loaded correctly.");
    } catch (UnsatisfiedLinkError ex) {
        // try load with absolute path
        setText("Error: E140tests.dll wasn't loaded!");
        setErrorFlag(true);
    }

E140tests.dll -> second file (compileted in MSVS)

#include "jni.h"
#include "jni_md.h"
#include "Lusbapi.h"
#include "LusbapiTypes.h"
#include "JNITEST2.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Class:     JNITEST2
 * Method:    ADCinit
 * Signature: (LJNITEST2;)V
 */
JNIEXPORT void JNICALL Java_JNITEST2_ADCinit
  (JNIEnv* env, jobject, jobject obj) {
  ...

lusbapi.dll -> third file, with another functions.

#ifndef __LusbapiH__
#define __LusbapiH__

// --------------------------------------------------------------------------
// ---------------------------- COMMON PART ---------------------------------
// --------------------------------------------------------------------------
#include <windows.h>
#include "LusbapiTypes.h"

If I throw my files in system32, all works too.

But. In another PC (xp, 7) my code doesn't works! Doesn't matter: if files(+dll) are in one folder, or if dll files are in system32 -> code can't find them.

I thought, that problem is in Runtime Libraries (MSVS), but wenn I installed them, nothing has changed...

(on my PC are IntelijIDEA, MSVS, jdk7.xx -> all works. I tested prog on another PC (with MSVS installed) -> and all worked. But on another -> dll wasn't found (and with Runtime Libraries installed too)).

i'll be waiting for help)

Andrew Evt
  • 3,613
  • 1
  • 19
  • 35
  • 1
    Did you try to examine dependencies with [Dependency Walker](http://www.dependencywalker.com)? – dnk Nov 01 '13 at 14:31
  • `Error: At least one required implicit or forwarded dependency was not found. Error: Modules with different CPU types were found.` on computer were doesn't works... – Andrew Evt Nov 01 '13 at 14:38
  • What is the architecture of the system that didn't work and the architecture of the system that is used to compile? – Sri Harsha Chilakapati Nov 01 '13 at 14:38
  • me system Is x32(x86) and errorSys -> x64. – Andrew Evt Nov 01 '13 at 14:40
  • Probably this explains why you're getting errors. [Load 32bit DLL library in 64bit application](http://stackoverflow.com/questions/2265023/load-32bit-dll-library-in-64bit-application) – dnk Nov 01 '13 at 14:49
  • with help of Dependency Walker I found 1 missing dll file, reinstall java and now all works correct. thanks @dnk and all, who tried to help! – Andrew Evt Nov 01 '13 at 15:36

3 Answers3

2

Unfortunately, when you compile the .DLL, it is only compatible with systems of matching architecture.

aka: 32-bit .DLL's work on 32-bit machines, the same goes for 64-bit. There are tactics to get around this (buying a licence for visual studio gives you tools that will allow this, and will produce platform-specific .dlls), but it means you have to bundle the appropriate .DLL with whatever version of the program you're testing. That's why on websites it asks if you have a 32-bit or 64-bit machine most of the time.

This is also one of the main reasons that java is nice, because it is 'platform independent' (I use that term loosely since other things can influence this to make it untrue).

Either way, as soon as you add JNI calls, you add a whole slew of dependencies that make it a little harder to distribute the software.

WillBD
  • 1,919
  • 1
  • 18
  • 26
  • i'm not sure. My friend have x64 system, and all works correct!.. but on another PC (with x64) -> doesn't – Andrew Evt Nov 01 '13 at 15:02
  • if that's the case, then it's likely a fluke that it happens to work on his and not another. Generally speaking, .DLL's are definitely platform specific, it'd be difficult to pinpoint the exact difference between the two platforms unless I knew the exact specs of both systems, and even then, the content of the .Dll's could make a difference. – WillBD Nov 01 '13 at 15:07
  • 1
    @AndrewEvt If it worked on your friend's 64-bit machine, he should have installed 32-bit Java. – Sri Harsha Chilakapati Nov 01 '13 at 15:09
  • This ^. I'd put some money on it, that he was compiling against a 32-bit JVM. good call Sri. – WillBD Nov 01 '13 at 15:10
0

You have to compile the DLL in both architectures. For compilation, you can use your 64-bit system and use these commands to compile.

For 64 bit (GCC)

gcc -o E140Tests64.dll -shared -IC:\....\include sourcefile.c

For 32 bit (GCC)

gcc -o E140Tests.dll -shared -IC:\....\include sourcefile.c

Hope this helps.

Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91
0

If you are going to distribute your application, you will want to build both 32bit and 64bit versions of your DLL. Then use the following technique to have the proper DLL loaded regardless of your customers JVM arch. Append either a 32 or a 64 (MyJniDLL32.dll & MyJniDLL64.dll) to your generated output file.

String archDataModel = System.getProperty("sun.arch.data.model");
System.loadLibrary(libraryName+archDataModel);

The arch of the DLL (32 vs 64) must match the JVM ach (32 vs 64 ), not the OS arch. If you are running a 32bit JVM on a 64bit OS, your Java code must have access to a 32bit DLL.

Java42
  • 7,628
  • 1
  • 32
  • 50