How do I detect which kind of JRE is installed — 32bit vs. 64bit

前端 未结 9 1130
离开以前
离开以前 2020-11-27 03:47

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 \"su

相关标签:
9条回答
  • 2020-11-27 04:27

    I'm using NSIS and Launch4j to wrap a Java Desktop app. So I need not only to detect any JRE, but the one Launch4j will find with its search algorithm. The only approach that made sense is to run a short Java program within the NSIS installer. Here's the Java:

    
        public class DetectJVM {
            private static final String keys [] = {
                "sun.arch.data.model",
                "com.ibm.vm.bitmode",
                "os.arch",
            };
            public static void main (String [] args) {
                boolean print = args.length > 0 && "-print".equals(args[0]);
                for (String key : keys ) {
                    String property = System.getProperty(key);
                    if (print) System.out.println(key + "=" + property);
                    if (property != null) {
                        int errCode = (property.indexOf("64") >= 0) ? 64 : 32;
                        if (print) System.out.println("err code=" + errCode);
                        System.exit(errCode);
                    }
                }
            }
        }
    
    

    Wrap this with Launch4J. Use the GUI header type but also set to true. Otherwise the error code will be lost. (I put all this in my Netbeans Ant build script.

    Here's the matching NSIS code that uses it:

    
    File ... ; unpack files including detectjvm.exe.
    ClearErrors
    ExecWait '"$INSTDIR\detectjvm.exe"' $0
    IfErrors DetectExecError
    IntCmp $0 0 DetectError DetectError DoneDetect
    DetectExecError:
        StrCpy $0 "exec error"
    DetectError:
        MessageBox MB_OK "Could not determine JVM architecture ($0). Assuming 32-bit."
        Goto NotX64
    DoneDetect:
    IntCmp $0 64 X64 NotX64 NotX64
    X64:
        File  ... 64-bit AMD DLLs.
        Goto DoneX64
    NotX64:
        File ... 32-bit x86 DLLs.
    DoneX64:
    Delete $INSTDIR\detectjvm.exe
    
    

    This has worked fine on a very large variety of machines from WinXP with no SP through Vista and Win7 with all SPs, 32- and 64-bit.

    Note that in my NSIS script I'm using an existing package that checks to see if the JVM is installed and does that first, so the default 32-bit selection would only occur if something went badly wrong with the JVM install, in which case the set of DLLs you copy won't matter anyway.

    Hope this is helpful to somebody.

    0 讨论(0)
  • 2020-11-27 04:28

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

    0 讨论(0)
  • 2020-11-27 04:30

    On linux, my (java) vm reports java.vm.name=Java HotSpot(TM) 64-Bit Server VM. The javadocs for System declare that System.getProperty will always have a value for this but are silent on sun.arch.data.model.

    Unfortunately they don't specify what the system property will be so some other JVM might just report java.vm.name=Edgar.

    BTW, by "installed on the system", I assume you mean "the current running JVM"?

    0 讨论(0)
  • 2020-11-27 04:35
    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)
    
    0 讨论(0)
  • 2020-11-27 04:37

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

    0 讨论(0)
  • 2020-11-27 04:38
    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());
      }
    }
    
    0 讨论(0)
提交回复
热议问题