如何检测安装了哪种 JRE -- 32 位与 64 位

2022-08-31 20:39:28

在使用 NSIS 安装程序进行安装期间,我需要检查系统上安装了哪个 JRE(32 位与 64 位)。我已经知道我可以检查系统属性“”,但这是特定于Sun的。我想知道是否有标准的解决方案。sun.arch.data.model


答案 1

可以使用“os.arch”属性检索正在使用的 JVM 体系结构:

System.getProperty("os.arch");

“os”部分似乎有点用词不当,或者也许最初的设计人员并不期望JVM在他们不是为之编写的架构上运行。返回值似乎不一致

NetBeans Installer 团队正在解决 JVM 与操作系统体系结构的问题。报价:

x64 位:Java 和系统

作为问题143434进行跟踪。

目前,我们使用jVM的x64位来确定系统(以及Platform.getHardwareArch())是否为64位。这绝对是错误的,因为可以在64位系统上运行32位JVM。我们应该找到一个解决方案来检查操作系统在32位JVM上运行时的真实64位。

  • 对于Windows,可以使用WindowsRegistry.IsWow64Process()来完成。
  • 对于 Linux - 通过检查 'uname -m/-p' == x86_64
  • 对于 Solaris,可以使用例如 'isainfo -b' 来完成
  • 对于Mac OSX,它不能使用uname参数来完成,可能可以通过创建64位二进制文件并在平台上执行来解决...(不幸的是,这不起作用:(我只用x86_64和ppc64 arch创建了二进制文件,并在Tiger上成功执行。
  • 对于通用Unix支持 - 它也不清楚...可能检查相同的“uname -m/-p”/“getconf LONG_BIT”,并将其与一些可能的64位值(x86_64,x64,amd64,ia64)进行比较。

来自不同 JVM 的示例属性,这些 JVM 都在 64 位 Ubuntu 8.0.4 上运行:

32 位 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

64位星期日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

64 位 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

(GNU版本没有报告“sun.arch.data.model”属性;可能其他JVM也没有。


答案 2

我正在使用NSIS和Launch4j来包装Java桌面应用程序。因此,我不仅需要检测任何JRE,还需要检测Launch4j通过其搜索算法找到的JRE。唯一有意义的方法是在NSIS安装程序中运行一个简短的Java程序。这是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);
                }
            }
        }
    }

用Launch4J包装它。使用 GUI 标头类型,但也设置为 true。否则,错误代码将丢失。(我把所有这些放在我的Netbeans Ant构建脚本中。

下面是使用它的匹配 NSIS 代码:

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

这在从没有SP的WinXP到Vista以及具有所有SP(32位和64位)的Win7的各种计算机上都运行良好。

请注意,在我的NSIS脚本中,我使用的是一个现有的软件包,该软件包检查JVM是否已安装并首先执行此操作,因此,仅当JVM安装出现问题时,才会进行默认的32位选择,在这种情况下,您复制的DLL集无论如何都无关紧要。

希望这对某人有帮助。


推荐