How do I detect which kind of JRE is installed — 3

2019-01-04 10:09发布

During installation with an NSIS installer, I need to check which JRE (32bit vs 64bit) is installed on a system. I already know that I can check a system property "sun.arch.data.model", but this is Sun-specific. I'm wondering if there is a standard solution for this.

9条回答
Rolldiameter
2楼-- · 2019-01-04 10:41
java -version

For a 64bit java version it'll print :

java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) ***64-Bit*** Server VM (build 25.92-b14, mixed mode)

For 32 bit it'll be just

java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) Client VM (build 25.92-b14, mixed mode)
查看更多
放荡不羁爱自由
3楼-- · 2019-01-04 10:44

When writing Java code, how do I distinguish between 32 and 64-bit operation?

http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_detection

There's no public API that allows you to distinguish between 32 and 64-bit operation. Think of 64-bit as just another platform in the write once, run anywhere tradition. However, if you'd like to write code which is platform specific (shame on you), the system property sun.arch.data.model has the value "32", "64", or "unknown".

查看更多
男人必须洒脱
4楼-- · 2019-01-04 10:50
import sun.misc.*;

import java.lang.reflect.*;

public class UnsafeTest {
  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
    unsafeField.setAccessible(true);
    Unsafe unsafe = (Unsafe) unsafeField.get(null);
    System.out.println(unsafe.addressSize());
  }
}
查看更多
放我归山
5楼-- · 2019-01-04 10:52

The JVM architecture in use can be retrieved using the "os.arch" property:

System.getProperty("os.arch");

The "os" part seems to be a bit of a misnomer, or perhaps the original designers did not expect JVMs to be running on architectures they weren't written for. Return values seem to be inconsistent.

The NetBeans Installer team are tackling the issue of JVM vs OS architecture. Quote:

x64 bit : Java and System

Tracked as the Issue 143434.

Currently we using x64 bit of JVM to determine if system (and thus Platform.getHardwareArch()) is 64-bit or not. This is definitely wrong since it is possible to run 32bit JVM on 64bit system. We should find a solution to check OS real 64-bitness in case of running on 32-bit JVM.

  • for Windows it can be done using WindowsRegistry.IsWow64Process()
  • for Linux - by checking 'uname -m/-p' == x86_64
  • for Solaris it can be done using e.g. 'isainfo -b'
  • for Mac OSX it can't be done using uname arguments, probably it can be solved by creating of 64-bit binary and executing on the platform... (unfortunately, this does not work:( I've created binary only with x86_64 and ppc64 arch and it was successfully executed on Tiger..)
  • for Generic Unix support - it is not clear as well... likely checking for the same 'uname -m/-p' / 'getconf LONG_BIT' and comparing it with some possible 64-bit values (x86_64, x64, amd64, ia64).

Sample properties from different JVMs all running on 64bit Ubuntu 8.0.4:

32bit IBM 1.5:

java.vendor=IBM Corporation
java.vendor.url=http://www.ibm.com/
java.version=1.5.0
java.vm.info=J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20061001 (JIT enabled)
J9VM - 20060915_08260_lHdSMR
JIT  - 20060908_1811_r8
GC   - 20060906_AA
java.vm.name=IBM J9 VM
java.vm.specification.name=Java Virtual Machine Specification
java.vm.specification.vendor=Sun Microsystems Inc.
java.vm.specification.version=1.0
java.vm.vendor=IBM Corporation
java.vm.version=2.3
os.arch=x86
os.name=Linux
os.version=2.6.24-23-generic
sun.arch.data.model=32

64bit Sun 1.6:

java.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi
java.version=1.6.0_05
java.vm.info=mixed mode
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vm.specification.name=Java Virtual Machine Specification
java.vm.specification.vendor=Sun Microsystems Inc.
java.vm.specification.version=1.0
java.vm.vendor=Sun Microsystems Inc.
java.vm.version=10.0-b19
os.arch=amd64
os.name=Linux
os.version=2.6.24-23-generic
sun.arch.data.model=64

64bit GNU 1.5:

java.vendor=Free Software Foundation, Inc.
java.vendor.url=http://gcc.gnu.org/java/
java.version=1.5.0
java.vm.info=GNU libgcj 4.2.4 (Ubuntu 4.2.4-1ubuntu3)
java.vm.name=GNU libgcj
java.vm.specification.name=Java(tm) Virtual Machine Specification
java.vm.specification.vendor=Sun Microsystems Inc.
java.vm.specification.version=1.0
java.vm.vendor=Free Software Foundation, Inc.
java.vm.version=4.2.4 (Ubuntu 4.2.4-1ubuntu3)
os.arch=x86_64
os.name=Linux
os.version=2.6.24-23-generic

(The GNU version does not report the "sun.arch.data.model" property; presumably other JVMs don't either.)

查看更多
forever°为你锁心
6楼-- · 2019-01-04 10:52

The following code checks the machineType field in any windows executable to determine if it is 32 or 64 bit:

public class ExeDetect
{
  public static void main(String[] args) throws Exception {
    File x64 = new File("C:/Program Files/Java/jre1.6.0_04/bin/java.exe");
    File x86 = new File("C:/Program Files (x86)/Java/jre1.6.0/bin/java.exe");
    System.out.println(is64Bit(x64));
    System.out.println(is64Bit(x86));
  }

  public static boolean is64Bit(File exe) throws IOException {
    InputStream is = new FileInputStream(exe);
    int magic = is.read() | is.read() << 8;
    if(magic != 0x5A4D) 
        throw new IOException("Invalid Exe");
    for(int i = 0; i < 58; i++) is.read(); // skip until pe offset
    int address = is.read() | is.read() << 8 | 
         is.read() << 16 | is.read() << 24;
    for(int i = 0; i < address - 60; i++) is.read(); // skip until pe header+4
    int machineType = is.read() | is.read() << 8;
    return machineType == 0x8664;
  }
}

Note that the code has been compacted for brevity...

查看更多
劳资没心,怎么记你
7楼-- · 2019-01-04 10:56

There might be both 32 bit and 64 bit JVM's available on the system, and plenty of them.

If you already have dll's for each supported platform - consider making a small executable which links and run so you can test if the platform supports a given functionality. If the executable links and run, you can install the corresponding shared libraries.

查看更多
登录 后发表回答