it-swarm.com.de

Wie erkenne ich, welche Art von JRE installiert ist - 32bit vs. 64bit?

Während der Installation mit einem NSIS-Installationsprogramm muss ich prüfen, welche JRE (32bit vs. 64bit) auf einem System installiert ist. Ich weiß bereits, dass ich eine Systemeigenschaft "Sun.Arch.data.model" prüfen kann, aber dies ist Sun-spezifisch. Ich frage mich, ob es dafür eine Standardlösung gibt.

49
user97629

Die verwendete JVM-Architektur kann mit der Eigenschaft " os.Arch " abgerufen werden:

System.getProperty("os.Arch");

Der "os" -Teil scheint ein Missverständnis zu sein, oder die ursprünglichen Designer haben nicht erwartet, dass JVMs auf Architekturen laufen, für die sie nicht geschrieben wurden. Die Rückgabewerte scheinen inkonsistent zu sein.

Das NetBeans-Installer-Team besteht aus befasst sich mit dem Problem von JVM vs. Zitat:

x64-Bit: Java und System

Verfolgt als Ausgabe 143434 .

Derzeit verwenden wir x64-Bit von JVM für Bestimmen Sie, ob das System (und damit Platform.getHardwareArch ()) 64-Bit .__ ist. oder nicht. Dies ist definitiv falsch seit Es ist möglich, 32-Bit-JVM auf .__ auszuführen. 64bit-System. Wir sollten eine .__ finden. Lösung zur Überprüfung der realen 64-Bit-OS des Betriebssystems Wenn Sie eine 32-Bit-JVM verwenden.

  • für Windows kann dies mit WindowsRegistry.IsWow64Process () durchgeführt werden.
  • für Linux: Aktivieren Sie "uname -m/-p" == x86_64
  • für Solaris kann dies z. 'isainfo -b'
  • für Mac OSX können keine uname-Argumente verwendet werden. Wahrscheinlich kann es .__ sein. gelöst durch Erstellen von 64-Bit-Binärdateien und auf der Plattform ausführen ... (leider funktioniert das nicht: ( Ich habe binär nur mit x86_64 und ppc64 Arch erstellt und es wurde erfolgreich auf Tiger ausgeführt ..)
  • für die Unterstützung von Generic Unix ist dies nicht eindeutig. Wahrscheinliche Überprüfung für die gleiche 'uname -m/-p'/'getconf LONG_BIT 'und Vergleich mit einigen mögliche 64-Bit-Werte (x86_64, x64, AMD64, ia64).

Beispieleigenschaften aus verschiedenen JVMs, die alle unter 64bit Ubuntu 8.0.4 ausgeführt werden:

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 So 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

(Die Version GNU meldet nicht die Eigenschaft "Sun.Arch.data.model"; vermutlich auch andere JVMs.)

48
McDowell

Ich verwende NSIS und Launch4j, um eine Java Desktop-App zu verpacken. Ich brauche also nicht nur JRE, sondern auch Launch4j mit seinem Suchalgorithmus. Der einzige sinnvolle Ansatz besteht darin, ein kurzes Java-Programm im NSIS-Installationsprogramm auszuführen. Hier ist das Java:

 öffentliche Klasse DetectJVM {
 private static final String-Schlüssel [] = {
 "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-Eigenschaft = System.getProperty (Schlüssel); 
 if (print) System.out.println (key + "=" + property); 
 if (Eigenschaft! = null) {
 int errCode = (property.indexOf ("64")> = 0)? 64: 32; 
 if (print) System.out.println ("err code =" + errCode); 
 System.exit (errCode); 
 } 
 } 
 } 
 } 

Wickle dies mit Launch4J ein. Verwenden Sie den GUI-Headertyp, setzen Sie ihn jedoch auf true. Andernfalls geht der Fehlercode verloren. (Ich füge das alles in mein Netbeans Ant-Build-Skript ein.

Hier ist der passende NSIS-Code, der ihn verwendet:

Datei ... ; Entpacken Sie Dateien einschließlich detectjvm.exe .
 ClearErrors 
 ExecWait '"$ INSTDIR\detectjvm.exe"' $ 0 
 IfErrors DetectExecError 
 IntCmp $ 0 0 DetectError DetectError DoneDetect 
 DetectExecError: 
 StrCpy $ 0 "exec-Fehler" 
 DetectError: 
 MessageBox MB_OK "Die JVM-Architektur konnte nicht ermittelt werden ($ 0). Angenommen, 32-Bit." 
 Gehe zu NotX64 
 DoneDetect: 
 IntCmp $ 0 64 X64 NotX64 NotX64 
 X64: 
 Datei ... 64-Bit-AMD-DLLs .
 Gehe zu DoneX64 
 NotX64: 
 Datei ... 32-Bit-x86-DLLs .
 DoneX64: 
 Löschen Sie $ INSTDIR\detectjvm.exe 

Dies hat auf einer Vielzahl von Maschinen von WinXP ohne SP bis Vista und Win7 mit allen SPs (32- und 64-Bit) gut funktioniert.

Beachten Sie, dass ich in meinem NSIS-Skript ein vorhandenes Paket verwende, das prüft, ob die JVM installiert ist und dies zuerst tut. Die standardmäßige 32-Bit-Auswahl würde nur dann erfolgen, wenn bei der JVM-Installation etwas schief gelaufen ist. In diesem Fall Die von Ihnen kopierten DLLs spielen sowieso keine Rolle.

Hoffe, das ist für jemanden hilfreich.

7
Gene

Wie unterscheide ich beim Schreiben von Java-Code zwischen 32- und 64-Bit-Operationen?

http://www.Oracle.com/technetwork/Java/hotspotfaq-138619.html#64bit_detection

Es gibt keine öffentliche API, mit der Sie zwischen 32 und .__ unterscheiden können. 64-Bit-Betrieb Stellen Sie sich 64-Bit als eine weitere Plattform in der .__ vor. einmal schreiben, irgendwo Tradition ausführen. Wenn Sie jedoch schreiben möchten Code, der plattformspezifisch ist (schade bei Ihnen), die Systemeigenschaft Sun.Arch.data.model hat den Wert "32", "64" oder "unknown".

4
billsimons
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());
  }
}
1
user188716
Java -version

Für eine 64-Bit-Java-Version wird Folgendes gedruckt:

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)

Für 32 Bit ist es einfach so

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
user6376564

Es können sowohl 32-Bit- als auch 64-Bit-JVMs auf dem System verfügbar sein, und zwar viele.

Wenn Sie bereits DLLs für jede unterstützte Plattform haben, sollten Sie eine kleine ausführbare Datei erstellen, die Links und Lauf ausführt, um zu testen, ob die Plattform eine bestimmte Funktionalität unterstützt. Wenn die ausführbare Datei verlinkt und ausgeführt wird, können Sie die entsprechenden gemeinsam genutzten Bibliotheken installieren.

Unter Linux meldet mein (Java) vm Java.vm.name = Java HotSpot (TM) 64-Bit-Server-VM. Die Javadocs für System erklären, dass System.getProperty immer einen Wert dafür hat, aber in Sun.Arch.data.model nicht angezeigt wird. 

Leider geben sie nicht an, wie die Systemeigenschaft aussehen wird, sodass eine andere JVM möglicherweise nur Java.vm.name = Edgar meldet. 

Übrigens, unter "auf dem System installiert" gehe ich davon aus, dass Sie "die aktuell ausgeführte JVM" meinen?

0
Steve B.