3

Possible Duplicate:
Java : switching between dll depends on system architecture (32/64)

In my Java application I need a JNI library which is available for 32 bit and 64 bit. I don't want to ship two different versions of my application so I want to ship the application with both libraries and the application must determine itself which library to load (foobar32.so or foobar64.so). How do I do that?

I thought about trying to load the first one and if this throws an exception then I load the second one but this sounds ugly.

Is there some system property I could check instead to determine if a 32 bit Java or a 64 bit Java is used to run my application? I know there is some os.arch property but the return value seems to be pretty unpredictable according to this answer.

So what is the best way to let the application decide if to load the 32 or 64 bit JNI library?

Community
  • 1
  • 1
kayahr
  • 20,913
  • 29
  • 99
  • 147
  • How're you bundling your application? In OSGi you have the ability to only load certain bundles or bundle fragments depending on the os architecture. This is how platform-specific functionality is delivered. Could you consider using OSGi? – katsharp Mar 27 '11 at 12:04
  • Your main concern is NOT what OS is but what the executable is: you can run 32bit executable on 64bit OS but then it is still 32bits and the libraries you need are 32bit not 64. If hypothetically you can run a 64bit executable on some 32bit OS, you need 64bit libraries. This is what przemelek tries to explain. `os.arch` will be good enough for practically anything as long as it is present, my answer was targeting cases when Unsafe will be there but some system property may not. – bestsss Mar 27 '11 at 14:12

2 Answers2

5

Why unpredictable? You want only to detect if it is 32 bit system, and in this case it will be always x86 (of course for x86 processors), everything else means 64 bit.

Problems starts if you know that your code may be executed also on PPC or other non x86 processors. But in this case you may use ugly hack with exception driven flow control, and use try {} catch () to "detect" such situations.

IMHO os.arch will be the best solution.

przemelek
  • 106
  • 1
  • 3
  • @przemelek - the `os.arch` is unreliable because it returns the properties of the system used for compiling the jar, not the system that it runs on (see link in my answer) – MByD Mar 27 '11 at 13:00
  • 1
    @MByD: No, the system property `os.arch` --- as all Java system properties --- is a runtime concept, not a compile time concept. Therefore, it returns the runtime architecture. – jmg Mar 27 '11 at 13:03
  • @jmg. I made a mistake. the return value from the `os.arch` is runtime value, but it is dependent on the bitness of the JRE, not the actual architecture, so if you have a 32bit JRE running on 64bit windows machine, you will get `x86` as a result. see this post: http://mark.koli.ch/2009/10/javas-osarch-system-property-is-the-bitness-of-the-jre-not-the-operating-system.html – MByD Mar 27 '11 at 13:09
  • 5
    @MByD: Ok, you're right in that. But, the "bitness" or the architecture of the running JVM is exactly what the OP needs to decide which library to load. – jmg Mar 27 '11 at 13:18
  • +1 @jmg, actually, you are right as well, and taught me important thing that was unclear to me. thanks. – MByD Mar 27 '11 at 13:25
  • Exactly, os.arch returns this in which mode is CPU executing JVM, and library must be created for this mode. 32 bit JVM will not be able to execute or even load 64 bit library, and 64 JVM will not be able to do this with 64 bit library. This isn't only "problem" for JVM, the same is in .NET. You cannot mix 32 and 64 bits. So os.arch tells you exactly this what is interesting for you :-) If it returns x86 you know that you should use 32 bit library. For anything else you may try to use 64 bit, it will not work only if your CPU is other than x86 (or rather x86_64). – przemelek Mar 27 '11 at 13:29
0

Unsafe.addressSize();

Report the size in bytes of a native pointer, as stored via {@link #putAddress}. This value will be either 4 or 8.

You can take it from here.

bestsss
  • 11,796
  • 3
  • 53
  • 63
  • If you mean _sun.misc.Unsafe_ then this is a bad thing to use because other Java implementations don't provide it. – kayahr Mar 27 '11 at 15:08
  • @kayahr, odds to have the native libs working on that java versions w/o Unsafe is practically none. – bestsss Mar 27 '11 at 15:17