1

I have a Java program uses some dlls. As these embeded dlls have to be built for a specific system architecture (32 or 64bits) I want to make a method/something that allow my program to switch between 32/64 bits version of dlls (or disable the library load if the program run on a 64 bits system)

I hope there is a solution different from making two versions of the program

Thanks in advance, Damien

Damien
  • 583
  • 3
  • 7
  • 18

5 Answers5

6

Use system properties:

if ("x86".equals(System.getProperty("os.arch"))) {
   // 32 bit
} else if ("x64".equals(System.getProperty("os.arch"))) {
   // 64 bit
}
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
3

You can use the System Property sun.arch.data.model

String dataModel = System.getProperty("sun.arch.data.model");
if("32").equals(dataModel){
    // load 32-bit DLL
}else if("64").equals(dataModel){
    // load 64-bit DLL
}else{
    // error handling
}

Careful: this property is defined on Sun VMs only!

Reference:

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
2

A brute force way is to run

boolean found = false;
for(String library: libraries)
    try {
        System.loadLibrary(library);
        found = true;
        break;
    } catch(UnsatisfiedLinkError ignored) {
    }
if(!found) throw new UnsatifiedLinkError("Could not load any of " + libraries);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

If you're using OSGi and JNI, you can specify the DLLs appropriate for different platforms and architectures in the manifest via Bundle-NativeCode.

For example:

    Bundle-NativeCode: libX.jnilib; osname=macOSX, X.dll;osname=win32;processor=x86
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • what about libraries having the same name? I have to import the rxtx library for both ARM and x86 architectures and the library is called librxtxSerial.so in both cases. How can i distinguish them using this header?? – wyr0 Sep 16 '15 at 15:53
  • @marbal - I think you would list the library twice, once for `processor=86`, and once for `processor=ARM_le` (for little-endian) or `processor=ARM_be` (for big-endian). These values and others can be found in the table at http://www.osgi.org/Specifications/Reference#processor . – Andy Thomas Sep 16 '15 at 18:39
  • I've created a folder named "lib" and 2 subfolders called "x86" and "arm" and i've put in each of them the libraries built respectively for processors x86 and arm. Then, in the header, i've wrote this: `lib/x86/librxtxSerial.so; processor=x86, lib/arm/librxtxSerial.so; processor=ARM_le` but every time i get the same error: `No match found for native code: ` . What i'm doing wrong? – wyr0 Sep 17 '15 at 08:22
  • i've descriibed the problem here: http://stackoverflow.com/questions/32625924/osgi-bundle-nativecode-give-error-no-match-found-for-native-code – wyr0 Sep 17 '15 at 08:58
0

Define a java interface that represents your DLL API and provide two implementations, one that calls the 32 bit DLL and another one that calls the 64 bit version:

public interface MyDll {
    public void myOperation();
}

public class My32BitDll implements MyDll {
    public void myOperation() {            
        // calls 32 bit DLL
    }
}

public class My64BitDll implements MyDll {
    public void myOperation() {            
        // calls 64 bit DLL
    }
}

public class Main {
    public static void main(String[] args) {
        MyDll myDll = null;

        if ("32".equals(args[0])) {
            myDll = new My32BitDll();
        } else if ("64".equals(args[0])) {
            myDll = new My64BitDll();
        } else {
            throw new IllegalArgumentException("Bad DLL version");
        }

        myDll.myOperation();
    }
}
gpeche
  • 21,974
  • 5
  • 38
  • 51
  • 1
    I doubt that this is what the OP wants. And it forces the user to tell the program whether it runs in a 32 bit or 64 bit environment. The program should discover that itself. – Christian Hujer Mar 11 '15 at 18:34