La version de ma jvm et les classpath

Soyez le premier à donner votre avis sur cette source.

Snippet vu 10 218 fois - Téléchargée 17 fois

Contenu du snippet

Bonjour,
ceci est un petit utilitaire pour connaitre la version de sa JVM et d'autres petits tricks de sa machine..

Source / Exemple :


import javax.*;

class ProprietesJVM {

	public static void main(String[] args) {
		// TODO Raccord de méthode auto-généré
String texte = "Bonjour "+ System.getProperty("user.name"); 

texte+= "\n\u25cf votre code pays/langue est"
	+System.getProperty("user.country")
+"/"+System.getProperty("user.language");
texte+= "\n\u25cf votre dossier personnel est "
	+System.getProperty("user.home");
texte+= "\n\u25cf votre dossier de travail est"
	+System.getProperty("user.dir");
texte+= "\n\u25cf  Votre system ("
	+System.getProperty("os.name")
    + ""+ System.getProperty("os.version")+"):";

texte+= "\n\u25cf utilise le caractère" 
		+System.getProperty("file.separator")
		+"comme séparateur de dossier";
texte+= "\n\u25cf Utilise le caractere"
	+System.getProperty("path.separator")+
	"comme separateur de chemin";

texte+= "\n\u25cf Votre JVM de version" +":"
       + System.getProperty("java.version");
texte+= "\n\u25cf Est istallé dans le dossier"
	+System.getProperty("java.home"); 
texte+= "\n\u25aa Utilise le classPath"
+ System.getProperty("java.class.path");

texte+= "\n\u25aa Est developpé par"
	 + System.getProperty("java.vendor");

texte+= "et disponible \u00e0 "
	+System.getProperty("java.vendor.url");
System.out.println(texte);
javax.swing.JOptionPane.showMessageDialog(null,texte);
System. exit(0);
		
		
		
		
}

			

	}

Conclusion :


Simple mais efficace pour ne plus se tromper de version de JVM lorsque la mise à jour (par exemple) est automatique.
Enjoy....

A voir également

Ajouter un commentaire

Commentaires

Messages postés
203
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
29 janvier 2019

Note: HashTable<K,V> a été modifié dans Java6 pour implémenter AUSSI l'interface Map<K,V>. Cela ne change pas l'arbre d'héritage (simple) de HashTable. Mais cela permet justement d'écrire la boite noire nécessaire. Du coup, HashTable n'est pas obsolète, au contraire de Dictionnary qui n'a pas subit le même traitemet (on se demande pourquoi ce qui était acceptable pour HashTable ne l'a pas été pour Dictionnary... sans doûte de sérieux problèmes de compatibilité du code de la librairie qui doit être capable de différencier une instance de Dictionnary d'une instance de Map par l'opération "instanceOf", et des problèmes de compatibilité lors de la désérialisation de flux sérialisés par une version précédente de Java, puisque cela modifie l'ordre de reconstruction des instances par les différents constructeurs d'objets de chaque type). Si on peut critiquer quelquechose dans la façon où la classe System a été étendue, est l'oubli de typage fort pour System.getProperties() qui se contente de retourner une "Enumeration<?>" alors qu'évidemment cela aurait dû être "Enumeration<String>" (quitte à ce que cela rende certaines implémentations de la ClassPath pour la JVM incompatible). Cela suggère que toutes les valeurs de clés retournées par System.getProperties ne sont pas forcément de type String (au contraire de ce que "dit" la classe "Properties"): c'est le cas en fait lors de l'initialisation de la JVM (quand la classe System est initialisée), même si plus tard dans nos programmes il ne reste que des clés de type String qui sont les seules accessibles par l'API documentée.

En revanche la class Properties a été étendue d'une autre façon: elle supporte la nouvelle méthode stringPropertyNames() qui retourne une "Enumeration<String>" sans qu'il soit nécessaire d'utiliser un typecast d'erasure (de la capture de ?) en Object (implicitement valide) ou String (quidoit êtrevérifié à l'exécution)

Aussi on peut écrire en Java6 bien plus proprement (plus aucun typecast):

java.util.Enumeration<String> cles =
System.getProperties().stringPropertyNames(); // pas de typecast ici!
while (cles.hasMoreElements()) {
String cle = cles.nextElement(); // pas de typecast ici !
System.out.println( cle + " = " + System.getProperty(cle) );
}

Cela répond au problème de performance (pas de vérification à l'exécution) et de sécurité du typage fort (vérification complète à la compilation). Mais ce n'est pas encore très pratique. On aimerait bien pouvoir simplifier cette syntaxe sansavoir à utiliser de variables d'états intermédiaires (source d'erreurs ou d'effets de bord dans les programmes).

Un exemple de classe miroir cachant le typecast effectué sur l'erasure des types "T<?>" en types "T", ici pour T=Enumeration:

class IterableEnumeration<T> implements java.util.Iterator<T> {
private final java.util.Enumeration<T> e;
public IterableEnumeration(java.util.Enumeration<T> e) {
this.e = e;
}
public boolean hasNext() {
return this.e.hasMoreElements();
}
public T next() {
return this.e.nextElement();
}
public void remove() {
throw new UnsupportedOperationException("Iterator's on IterableEnumeration's are not removable");
}
}

On peut alors étendre Properties de cette façon (fonctionne aussi en Java 1.5) :

class IterableProperties extends java.util.Properties implements java.lang.Iterable{
public IterableProperties(java.util.Properties p) {
super(p);
}
public IterableEnumeration<String> iterator() {
return new IterableEnumeration<String>((java.util.Enumeration<String>)this.propertyNames()); // warning sur l'erasure...
}
}
Noter que ci-dessus l'erasure a été isolée dans le typecast de la méthode iterator, pour lequel il est simple de vérifier que l'ensemble retourné par propertyNames() ne contient que des String et non n'importe quel type d'objet.

On peut encore faire mieux en Java6 (pour Java 1.5 la version précédente sera nécessaire) pour éviter ce warning, en employant la méthode stringPropertyNames pour lequel cette assomption est totalement évitée:

class IterableProperties extends java.util.Properties implements java.lang.Iterable {
public IterableProperties(java.util.Properties p) {
super(p);
}
public IterableEnumeration<String> iterator() {
return new IterableEnumeration<String>((java.util.Enumeration<String>)this.stringPropertyNames());
}
}

Et ensuite on peut écrire de façon totalement sûre (grace au typage fort):

for (String cle : new IterableProperties(System.getProperties()).iterator())
System.out.println(cle + " = " + System.getProperty(cle))

C'est exactement ce qu'on voulait: plus de variable intermédiaire, pas même pour l'itérateur, plus moyen d'échapper au contrôle de "scope", et un programme totalement vérifiable (car totalement dépourvu de variable d'état ayant des effets de bord possibles), performant (plus de contrôle de type à l'exécution, ceci étant totalement vérifié par le compilateur).
Messages postés
203
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
29 janvier 2019

Variante sans utiliser aucun typecast (donc sans vérification de type à l'exécution pour chaque clé, mais directment à la compilation), pour Java 6:

for (java.util.Map.Entry<String, Object> e : System.getProperties().entrySet())
System.out.println(e.getkey() + " = " + e.getValue());

Ladifférence ici est queentrySet est hérité de HashTable mais ne contient pasla liste deséléments hérités pour les valeurs par défaut (normalement il n'y a pas d'héritage de valeurs par défaut pour les propriétés de System).

Mais on peut alors vouloir utiliser propertyNames() pour avoir aussi les valeurs héritées, et le source précédent devient (en Java 6):

for (String cle : System.getProperties().propertyNames())
System.out.println( cle + " = " + System.getProperty(cle) );

ce qui serait finalement bien mieux (cela fait appel en interne au polymorphisme à typage fort de propertyNames() qui en Java 6 retourne une valeur de type polymorphe "Enumeration<?>", et non de type plus spécialisé "Enumeration" (monomorphe) qui en est dérivé (<?> y prend la valeur <Object> et ce type dérivé demandera donc un typecast "(String)", verifié à l'exécution pour convertir une instance de type "Object" en "String" pour revenir au type parent polymorphe et vérifier que l'Object est convertible en String, ce qui n'est possible que si les éléments dans la liste de propriété supportent l'opération toString().

L'autre solution serait de sous-typer explicitement l'Enumeration retournée par propertyNames(), ce qui ne nécessiterait qu'un seul typecast, hors de la boucle:

java.util.Enumeration<String> cles = System.getProperties().propertyNames();
for (String cle : cles)
System.out.println( cle + " = " + System.getProperty(cle) );

ou encore de façon équivalente, sans déclaration de variable temporaire:

for (String cle : (java.util.Enumeration<String>)System.getProperties().propertyNames())
System.out.println( cle + " = " + System.getProperty(cle) );

Malheureusement, cela ne marche toujours pas car le type "Enumeration<?>" n'implémente pas l'interface "Iterable" nécessaire pour utiliser la boucle for simplifiée (ceci pour des raisons historiques de compatibilité ascendante, le type Enumeration n'ayant pas été conçu initialement comme implémentant cette interface, il n'est donc pas compatible)...

En attendant on peut toujours écrire (sans typecast dans la boucle):

java.util.Enumeration<String> cles =
(java.util.Enumeration<String>)System.getProperties().propertyNames();
while (cles.hasMoreElements()) {
String cle = cles.nextElement(); // pas de typecast ici !
System.out.println( cle + " = " + System.getProperty(cle) );
}

On n'a plus de typechecking dans la boucle mais un typechecking dans l'expression affectée à l'initialisation de la variable "cles". Ce typechecking est résiduel et signalé comme efectuant un typechecking sur l'erasure "Enumeration" et non "Enumeration<?>", c'est valide mais peu sûr.

Alors comment éviter le typecast à chaque boucle et des warning partout? L'idée est de créer un type (une classe en Java) dérivé de "Enumeration<?>" et implémentant l'interface "java.util.Iterable". Pas évident, car "Properties<K,V>" hérite de "HashTable<K,V>" qui n'est pas une Collection mais hérite de la classe "Dictionnary<K,V>" (lui même dérivé directement de Object et non de l'interface "Map<K,V>"). Là encore la raison est historique...

La doc de Java a beau dire que java.util.Dictionnary est obsolète, on ne peut s'en passer ni pour HashTable, ni pour Properties et donc pas non plus pour la classe System qui devraient toutes devenir obsolètes pour être remplacées par de nouvelles classes se basant sur "Collection".

Voilà quelques manques dans l'API du JDK pour rendre le typage plus fort dans Java 6, et permettre de bannir totalement le typecast dans un projet complexe.

Il y a des projets qui l'exigent, et activent une option du compilateur signalant TOUS les typecasts (et les "erasures" de types polymorphes en types simples) et les recencent systématiquement, même ceux qui sont à priori autorisés par le langage, car la vérification à l'exécution est source d'ennuis imprévisibles et complique sérieusement la vérification du code: dans des cas comme ça on est obligé d'encapsuler cette opération dans une "boîte noire" et former des batteries de tests assez conséquentes, avec de nombreuses assertions à vérifier, et des tonnes de commentaires pour le justifier.

Pour des cas comme ça, on cherche à isoler le problème et on construit des classes "miroirs" comme Map par rapport à Dictionnary, mais aussi les miroirs de HashTable, Properties et System, et on marque ces anciennes classes comme obsolètes et à remplacer par leur "miroir" plus sécurisés et agissant comme boîtes noires testées isolément.
Messages postés
32
Date d'inscription
jeudi 20 septembre 2007
Statut
Membre
Dernière intervention
19 janvier 2009

Bravo Celphys2 ca c'est cool.
Citer ses sources et ne rien s'attribuer est tellement rare.
Chapeau bas, monseigneur.
Messages postés
496
Date d'inscription
mercredi 30 juin 2004
Statut
Membre
Dernière intervention
29 juillet 2009
1
celphys2, belle honnêteté intellectuelle!
Messages postés
8
Date d'inscription
vendredi 24 mars 2006
Statut
Membre
Dernière intervention
3 mars 2009

En effet ta source est pratique. Cependant si vous souhaitez obtenir la liste complète des propriétés 'System' vous pouvez utiliser :

java.util.Enumeration liste = System.getProperties().propertyNames();
String cle;
while( liste.hasMoreElements() ) {
cle = (String)liste.nextElement();
System.out.println( cle + " = " + System.getProperty(cle) );
}

Cette source est extraite de la FAQ de developpez.com que vous trouvez sur : http://java.developpez.com/faq/java/?page=systeme#SYSTEME_variable_environnement

L'auteur en est Clément Cunin. Je ne pense pas qu'il m'en voudra de la promouvoir.
Afficher les 7 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.