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