Java/DetectJre

Cette page a été rédigée il y a fort fort longtemps, et n'a pas tellement été mise à jour.

 

Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise page. Moi, si je devais résumer mon wiki aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-être à un moment où je ne pouvais pas, où j'étais seul chez moi. Et c'est assez curieux de se dire que les hasards, les rencontres forgent une destinée... Parce que quand on a le goût de la chose, quand on a le goût de la chose bien faite, le beau geste, parfois on ne trouve pas l'interlocuteur en face je dirais, le miroir qui vous aide à avancer. Alors ça n'est pas mon cas, comme je disais là, puisque moi au contraire, j'ai pu ; et je dis merci au wiki, je lui dis merci, je chante le wiki, je danse le wiki... je ne suis qu'amour ! Et finalement, quand des gens me disent « Mais comment fais-tu pour avoir cette humanité ? », je leur réponds très simplement que c'est ce goût de l'amour, ce goût donc qui m'a poussé aujourd'hui à entreprendre une construction logicielle... mais demain qui sait ? Peut-être simplement à me mettre au service de la communauté, à faire le don, le don de soi.

Qui n’a jamais été confronté au problème de mise à jour des scripts ? On développe ou adapte des script Windows ou shell pour lancer nos programmes java, que ce soit pour des applications standard ou des serveurs d’applications, mais la portabilité de ces scripts se trouve limité par la localisation de la JRE ou du JDK.

Les techniques présentées ci-dessous concernent les JDK et JRE de Sun.

Techniques générales

Java dans le path

Les solutions les plus simples auxquelles on pense immédiatement, consistent à lancer l’exécutable java ou javac, en lui demandant la version. Ceci fonctionne très bien si l’exécutable en question a été mis dans le path.

java -version

Affiche

Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)

On constate que c’est un JRE, version 6 de Sun (cf. HotSpot).

javac -version

Affiche

Eclipse Java Compiler v_774_R33x, 3.3.1, Copyright IBM Corp 2000, 2007. All rights reserved.

On constate que le compilateur par défaut est celui d’Eclipse.

Pour retrouver le répertoire d’installation, sous Linux, il faut remonter les liens symboliques de façon récursive.

#!/bin/sh
javac_path=which javac
while [ -L $javac_path ]
do
  javac_ln=ls -l $javac_path
  javac_path=echo $javac_ln | sed -e 's/.* -> //'
done
echo $javac_path

Variable JAVA_HOME

Cette variable est demandée par beaucoup de programmes. Les scripts qui sont présentés ici servent souvent à renseigner une telle variable. Cependant, si elle est renseignée au niveau du système, celà nous facilite le travail. A condition toutefois que la version soit la bonne.

sous Linux :

$JAVA_HOME/bin/java -version   # pour un JRE
$JAVA_HOME/bin/javac -version  # pour un JDK

sous Windows :

%JAVA_HOME%\bin\java -version   # pour un JRE
%JAVA_HOME%\bin\javac -version  # pour un JDK

Techniques Windows

Sous Windows, les JRE et JDK de Sun s’inscrivent dans la base de registre au moment de l’installation. Il suffit donc de savoir chercher au bon endroit pour trouver l’information nécessaire.

Script

Le script ci-dessous recherche un JDK v6 et positionne la variable JAVA_HOME dessus.

set exp1=reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\1.6" /v JavaHome
set exp2=findstr /I /L /C:"REG_SZ"
for /f "tokens=1,2,3" %%a in ('%exp1%^|%exp2%') do set JAVA_HOME=%%c
rem echo %JAVA_HOME%

Table de registre

L’organisation du registre est la suivante :

  • Les JDK sont enregistrés dans le répertoire HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit, avec 1 sous-répertoire par version majeure et 1 sous-répertoire par numéro d’update. La clé CurrentVersion à la racine de ce répertoire indique la version par défaut.

  • Les JRE sont enregistrés dans le répertoire HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment, avec la même organisation que pour les JDK : sous-répertoires et clé CurrentVersion.

Par exemple, sur mon poste, j’ai 2 JDK et 1 JRE, ce qui donne ceci

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\

  • Java Development Kit

    • CurrentVersion = 1.6

  • 1.5

    • JavaHome = C:\DevJava\jdk1.5.0_16

  • 1.5.0_16

    • JavaHome = C:\DevJava\jdk1.5.0_16

  • 1.6

    • JavaHome = C:\DevJava\jdk1.6.0_11

  • 1.6.0_11

    • JavaHome = C:\DevJava\jdk1.6.0_11

  • Java Runtime Environment

    • CurrentVersion = 1.6

  • 1.6

    • JavaHome = C:\Program Files\Java\jre6

  • 1.6.0_11

    • JavaHome = C:\Program Files\Java\jre6

On notera que c’est encore l’ancienne numérotation des versions que est utilisée : 1.6 au lieu de 6.

On peut encore trouver quelques autres informations, concernant Web Start et le Java Plug-in.

Techniques Linux

Pour détecter l’installation d’un JDK ou d’une JRE sous Linux, on peut interroger le système d’installation par dépôts, avec les utilitaires rpm ou apt-get, ou utiliser des commandes spécifiques, donnant la liste des alternatives connues du système pour Java.

Alternatives Java

Sous Ubuntu / Debian, la commande update-java-alternatives donne une liste des JRE et JDK installés dans /usr/lib/jvm/. Pour limiter la recherche aux JRE, on ajoute l’argument --jre.

update-java-alternatives -l
update-java-alternatives --jre -l

Cette commande fait partie du paquet java-common, qu’il faut avoir installé au préalable.

En associant cette commande avec grep et awk, on arrive à extraire le chemin d’installation d’une JRE ou d’un JDK :

export JAVA_HOME=update-java-alternatives -l | grep java-6-openjdk | awk '{ print $3 }'

⇒ /usr/lib/jvm/java-6-openjdk

La même commande permet de forcer la version de java par défaut.

sudo update-java-alternatives -s java-6-openjdk

Sous RedHat, l’équivalent est la commande alternatives.

alternatives --display java

Paquets Ubuntu / Debian

Installation de Java

Ces systèmes utilisent apt-get. Pour poser les bonnes questions à l’utilitaire, il faut connaître comment est construit le nom des paquets. Sur Ubuntu, les JDK ont des noms du type sun-java5-jdk, et les JRE, sun-java5-jre.

L’installation d’un JDK 5 se fait par la commande suivante :

 sudo apt-get install sun-java5-jdk

L’installation d’une JRE 5 se fait par la commande suivante :

 sudo apt-get install sun-java5-jre

Cette règle est mise à mal si on utilise d’autres JDK ou JRE, comme ceux de Oracle/BEA ou d’IBM, voire OpenJDK. Les scripts devront être adaptés.

Détection de Java

Dans ces conditions, les commandes suivantes détectent les JRE qui sont installées :

dpkg -l | grep '^ii' | awk '{print $2}' | grep '^sun-java[1-9]-jre'
dpkg -l | grep '^ii' | awk '{print $2}' | grep '^sun-java[1-9]-bin'

Alors que celle-ci détecte les JDK :

dpkg -l | grep '^ii' | awk '{print $2}' | grep '^sun-java[1-9]-jdk'

Recherche des répertoires d’installation

Un script peut alors utiliser ces informations pour rechercher les répertoires d’installation des JDK ou JRE, en limitant aux versions 5 et 6.

#!/bin/sh

# 1° étape : rechercher les paquets installés
for jvm in dpkg -l | grep '^ii' | awk '{print $2}' | grep '^sun-java[5-6]-jdk' # remplacer jdk par bin pour chercher les jre
do
   # 2° étape : rechercher où est installé l'exécutable javac
   javac_allpath=sudo dpkg -L $jvm | grep 'bin/javac$' # remplacer javac par java pour chercher les jre
   # 3° étape : parcourir les exécutables trouvés
   for javac_path in $javac_allpath
   do
      # On élimine les liens symboliques
      if [ ! -L $javac_path ]
      then
         javabin_path=dirname $javac_path
         echo dirname $javabin_path
      fi
   done
done