web-dev-qa-db-fra.com

Comment détecter le type de JRE installé: 32 bits et 64 bits

Lors de l'installation avec un programme d'installation NSIS, je dois vérifier quel JRE (32 bits par rapport à 64 bits) est installé sur un système. Je sais déjà que je peux vérifier une propriété système "Sun.Arch.data.model", mais cela est spécifique à Sun. Je me demande s'il existe une solution standard pour cela.

49
user97629

L'architecture JVM utilisée peut être récupérée à l'aide de la propriété " os.Arch ":

System.getProperty("os.Arch");

La partie "os" semble être un peu impropre, ou peut-être que les concepteurs d'origine ne s'attendaient pas à ce que les machines virtuelles fonctionnent sur des architectures pour lesquelles elles n'ont pas été écrites. Les valeurs renvoyées semblent être incohérentes .

L’équipe du programme d’installation de NetBeans est composée de s’attaquant au problème de l’architecture JVM vs OS. Citation:

x64 bit: Java et System

Suivi en tant que numéro 143434 .

Actuellement, nous utilisons un bit x64 de JVM pour déterminer si system (et donc Platform.getHardwareArch ()) est 64 bits ou pas. C'est définitivement faux depuis il est possible d’exécuter une machine virtuelle Java 32 bits sur Système 64 bits. Nous devrions trouver un solution pour vérifier l'OS réel 64 bits en cas d'exécution sur JVM 32 bits.

  • pour Windows cela peut être fait en utilisant WindowsRegistry.IsWow64Process ()
  • pour Linux - en cochant 'uname -m/-p' == x86_64
  • pour Solaris, cela peut être fait en utilisant, par exemple, 'isainfo -b'
  • pour Mac OSX, cela ne peut pas être fait avec des arguments uname, mais probablement résolu en créant du binaire 64 bits et en exécutant sur la plate-forme ... (Malheureusement, cela ne fonctionne pas: ( J'ai créé le binaire uniquement avec x86_64 et ppc64 Arch et il a été exécuté avec succès exécuté sur Tiger ..)
  • pour le support Unix générique - ce n’est pas clair non plus ... vérification probable pour le même 'uname -m/-p'/'getconf LONG_BIT 'et en le comparant avec certains valeurs 64 bits possibles (x86_64, x64, AMD64, ia64).

Exemples de propriétés de différentes machines virtuelles s'exécutant sur Ubuntu 8.0.4 64 bits:

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

(La version GNU ne rapporte pas la propriété "Sun.Arch.data.model"; vraisemblablement les autres machines virtuelles ne le font pas non plus.)

48
McDowell

J'utilise NSIS et Launch4j pour envelopper une application Java Desktop. Il me faut donc non seulement détecter tout JRE, mais celui que Launch4j trouvera avec son algorithme de recherche. La seule approche sensée consiste à exécuter un court programme Java au sein du programme d’installation NSIS. Voici le Java:


 Classe publique DetectJVM {
 privé statique final des clés de chaîne [] = {
 "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]); 
 pour (clé de chaîne: clés) {
 Propriété de chaîne = System.getProperty (key); 
 if (print) System.out.println (clé + "=" + propriété); 
 si (propriété! = null) {
 int errCode = (property.indexOf ("64")> = 0)? 64: 32; 
 if (print) System.out.println ("err code =" + errCode); 
 System.exit (errCode); 
 } 
 } 
 } 
 } 

Enveloppez cela avec Launch4J. Utilisez le type d’en-tête de l’interface graphique, mais définissez-le également sur true. Sinon, le code d'erreur sera perdu. (Je mets tout cela dans mon script de compilation Netbeans Ant.

Voici le code NSIS correspondant qui l'utilise:


Fichier ... ; décompressez les fichiers, y compris 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 "Impossible de déterminer l'architecture JVM ($ 0). En supposant 32 bits." 
 Allez à NotX64 
 DoneDetect: 
 IntCmp $ 0 64 X64 NotX64 NotX64 
 X64: 
 Fichier ... DLL AMD 64 bits .
 Allez à DoneX64 
 NotX64: 
 Fichier ... DLL x86 32 bits .
 DoneX64: 
 Supprimez $ INSTDIR\detectjvm.exe 

Cela a bien fonctionné sur une très grande variété de machines de WinXP sans SP à Vista et Win7 avec tous les SP, 32 et 64 bits.

Notez que dans mon script NSIS, j'utilise un paquet existant qui vérifie si la machine virtuelle est installée et le fait en premier. La sélection 32 bits par défaut ne se produira que si quelque chose ne va pas avec l'installation de la machine virtuelle, auquel cas l'ensemble des DLL que vous copiez n'aura pas d'importance de toute façon.

J'espère que cela est utile à quelqu'un.

7
Gene

Lors de l'écriture de code Java, comment distinguer les opérations 32 bits et 64 bits?

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

Aucune API publique ne vous permet de faire la distinction entre 32 et Opération 64 bits. Pensez à 64 bits comme une autre plate-forme dans le écrivez une fois, courez n'importe où la tradition. Cependant, si vous souhaitez écrire code qui est spécifique à la plate-forme (honte à vous), la propriété système Sun.Arch.data.model a la valeur "32", "64" ou "inconnu".

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

Pour une version Java 64bits, ça va imprimer:

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)

Pour 32 bits ce sera juste

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

Il est possible que des JVM 32 bits et 64 bits soient disponibles sur le système, et beaucoup d’entre elles.

Si vous avez déjà des dll pour chaque plate-forme prise en charge, envisagez de créer un petit exécutable avec des liens et exécutez-le afin de pouvoir vérifier si la plate-forme prend en charge une fonctionnalité donnée. Si le fichier exécutable est lié et exécuté, vous pouvez installer les bibliothèques partagées correspondantes.

Sur linux, mes rapports (Java) vm sont Java.vm.name = Ordinateur virtuel Java HotSpot (TM) 64 bits. Les javadocs de System déclarent que System.getProperty aura toujours une valeur pour cela, mais reste silencieux sous Sun.Arch.data.model. 

Malheureusement, ils ne spécifient pas quelle sera la propriété système, aussi une autre machine virtuelle Java pourrait-elle simplement signaler Java.vm.name = Edgar. 

BTW, par "installé sur le système", je suppose que vous voulez dire "la JVM en cours d'exécution"?

0
Steve B.