Créer votre propre système de mise à jour en Java
Date de publication : 24 Juillet 2006
Par
Baptiste Wicht (home)
(1 commentaire)
Avec ce tutoriel, vous allez apprendre à créer votre propre système de mise à jour en Java. Ainsi, vous pourrez ajouter une simple option dans votre application pour permettre à l'utilisateur de mettre à jour son application.
I. Introduction
II. Récupération de la version
III. Télécharger la dernière version
IV. Création d'un lanceur
V. Application du protocole
VI. Conclusion
VI-A. Conclusion
VI-B. Les sources
I. Introduction
Nous allons réaliser ce système en Java, mais il est tout à fait possible d'adapter mon protocole dans la quasi-totalité des langages de programmation.
Tout d'abord, avant de commencer à coder le moindre code, il nous faut définir un "protocole" de mise à jour. Ce "protocole devra définir les différentes étapes dans la mise à jour de notre programme".
Voilà le protocole que je propose pour ce tutoriel :
- On récupère les versions disponibles sur internet
- On les compare avec la version actuelle
- Si la version actuelle est plus récente, on affiche un message disant à l'utilisateur qu'il n'y a pas de mise à jour possible
- Sinon, on informe l'utilisateur des versions possibles et on lui donne le choix quand à laquelle télécharger.
- S'il veut en télécharger une, on télécharge celle qu'il a choisie
- Ensuite, on redémarre le programme
- Le programme au démarrage doit voir s'il y a une nouvelle version, et le cas échéant, la prendre ==> utilisation d'un lanceur.
Je n'ai pas la prétention de dire que ce "protocole" est le meilleur, mais c'est celui que l'on va employer pour ce tutoriel, rien ne vous empêche d'ailleurs de le modifier.
Avant de mettre en oeuvre notre protocole, on va d'abord apprendre à réaliser les opérations compliquées de ce tutoriel et ensuite mettre ensemble le tout.
II. Récupération de la version
Pour qu'on puisse récupérer la dernière version, il faut que celle-ci soit stockée quelque part et accessible. Quoi de plus accessible qu'internet ? Et quoi de plus pratique qu'un fichier XML ? On va donc employer un fichier XML hébergé sur internet. Ce fichier devra contenir en tout cas un champ contenant la version :
<?xml version="1.0" encoding="ISO-8859-1"?>
<versions>
<version>
<nom>Numéro de version</nom>
<files>
<file>
<url>Chemin vers le fichier</url>
<destination>Destination relative</destination>
</file>
</files>
</version>
</versions>
|
Ainsi, avec un fichier XML pareil, vous pouvez avoir plusieurs versions disponibles sur internet, qui peuvent demander plusieurs fichiers à télécharger.
Voilà, vous avez maintenant une page avec les dernières versions à jour de votre application, mais maintenant, il s'agit de la récupérer ces version.
On va donc récupérer le flux de ce fichier XML et le parser avec l'Api JDOM (si vous voulez vous familiariser avec cet api, je ne peut que vous conseiller
ce tutoriel). On va donc récupérer toutes les versions disponibles.
private String xmlPath = "Lien vers fichier XML";
private Document xmlDocument = null;
private ArrayList<String> getVersions(){
ArrayList<String> versions = new ArrayList<String>();
try {
URL xmlUrl = new URL(xmlPath);
URLConnection urlConnection = xmlUrl.openConnection();
urlConnection.setUseCaches(false);
urlConnection.connect();
InputStream stream = urlConnection.getInputStream();
SAXBuilder sxb = new SAXBuilder();
try {xmlDocument = sxb.build(stream);
} catch (JDOMException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();}
Element racine = xmlDocument.getRootElement();
List listVersions = racine.getChildren("version");
Iterator iteratorVersions = listVersions.iterator();
while(iteratorVersions.hasNext()){
Element version = (Element)iteratorVersions.next();
Element elementNom = version.getChild("nom");
versions.add(elementNom.getText());
}
Collections.sort(versions);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return versions;
}
|
Voilà, vous arrivez maintenant à récupérer la dernière version disponible.
Vous avez remarqué qu'on ne fait pas de test dans le cas ou la version n'a pas pu être récupérée, mais on fera ces tests, quand on récupéra la dernière version.
III. Télécharger la dernière version
Maintenant que l'on a récupéré la dernière version disponible, il faut aussi bien entendu la télécharger.
Donc il faut aussi que votre fichier .jar soit disponible sur le serveur, vous devrez donc aussi l'héberger quelque part.
Pour récupérer ce fichier sur internet, on va donc de nouveau établir une connexion par URL et cette fois on va lire l'entier du fichier. Et ensuite écrire tous ces bits dans le fichier en local, dont le chemin est passé en paramètre. Il faudra juste nommer d'une façon différente le fichier qu'on vient de téléchargé et le fichier sur lequel on travaille actuellement.
private void downloadFile(String filePath, String destination) {
URLConnection connection = null;
InputStream is = null;
FileOutputStream destinationFile = null;
try {
URL url = new URL(filePath);
connection = url.openConnection( );
int length = connection.getContentLength();
if(length == -1){
throw new IOException("Fichier vide");
}
is = new BufferedInputStream(connection.getInputStream());
byte[] data = new byte[length];
int currentBit = 0;
int deplacement = 0;
while(deplacement < length){
currentBit = is.read(data, deplacement, data.length-deplacement);
if(currentBit == -1)break;
deplacement += currentBit;
}
if(deplacement != length){
throw new IOException("Le fichier n'a pas été lu en entier (seulement "
+ deplacement + " sur " + length + ")");
}
destinationFile = new FileOutputStream(destination);
destinationFile.write(data);
destinationFile.flush();
} catch (MalformedURLException e) {
System.err.println("Problème avec l'URL : " + filePath);
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
is.close();
destinationFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
|
Le code est suffisamment commenté pour que tout le monde comprenne chaque étape de l'opération de l'opération. Je me passerai donc de commentaires supplémentaires sur cette méthode.
IV. Création d'un lanceur
Maintenant que l'on a récupéré le numéro de version, le nouveau fichier, il va falloir créer notre lanceur.
Concrètement, à quoi va-t-il servir ? Eh bien tout simplement, il va vérifier si l'on a téléchargé une nouvelle version ou non. Dans le cas ou il y a une nouvelle version, il va la renommer, supprimer l'ancienne et lancer la nouvelle et dans le cas ou il n'y en aurait pas, il va tout simplement lancer l'actuelle.
Pour lancer notre programme, j'ai choisi d'employer JDIC. Pourquoi ? Tout simplement, parce qu'avec JDIC, on conserve une portabilité parfaite et ainsi votre code marchera sous Windows, Linux et Mac. Vous pouvez aller le télécharger
ici. Vous pouvez aussi lire
cet article pour en savoir plus.
Notre lanceur sera un tout petit programme, composé d'une seule méthode main et de plusieurs champs.
import java.io.File;
import javax.swing.JOptionPane;
import org.jdesktop.jdic.desktop.Desktop;
import org.jdesktop.jdic.desktop.DesktopException;
public class Lanceur {
private static final String pathCurrent = File.separator + "Actual.jar";
private static final String pathNew = File.separator + "New.jar";
private static final String pathOld = File.separator + "Old.jar";
private static final String currentFolder = System.getProperty("user.dir");
public static void main(String[] args) {
File current = new File(currentFolder + pathCurrent);
File newVersion = new File(currentFolder + pathNew);
File old = new File(currentFolder + pathOld);
if(newVersion.exists()){
current.renameTo(old);
newVersion.renameTo(current);
old.delete();
try {
Desktop.open(current);
} catch (DesktopException e) {
e.printStackTrace();
}
}else if(current.exists()){
try {
Desktop.open(current);
} catch (DesktopException e) {
e.printStackTrace();
}
}else{
JOptionPane.showMessageDialog(null,"Aucun fichier jar à lancer...");
}
}
}
|
Comme vous le voyez, c'est extrêmement simple comme classe. Il faut juste renseigner les champs pathCurrent, pathOld et pathNew et le programme s'occupe de tout, c'est transparent pour l'utilisateur.
La seule chose qui va changer avec l'emploi d'un lanceur, c'est le fait que l'utilisateur ne devra plus lancer directement votre programme mais le lanceur, s'il veut nécessiter des mises à jour.
V. Application du protocole
Maintenant que l'on sait comment faire les parties compliquées, on va appliquer notre "protocole". On va donc créer une classe Updater avec les 2 méthodes créées précédemment et une nouvelle que l'on va faire maintenant.
private String lanceurPath = "Chemin vers lanceur";
private String version = "XXX";
private String currentFolder = System.getProperty("user.dir");
public void update(){
ArrayList<String> versions = getVersions();
if(versions.size() == 0){
JOptionPane.showMessageDialog(null,"Impossible de se connecter au service, vérifiez votre " +
"connection internet");
}else{
if(!versions.get(versions.size() - 1).equals(version)){
String versionChoisie = (String)JOptionPane.showInputDialog(null,"Choississez la version à " +
"installer", "Versions disponibles",JOptionPane.QUESTION_MESSAGE,
null,versions.toArray(),versions.get(versions.size() - 1));
if(versionChoisie != ""){
Element racine = xmlDocument.getRootElement();
List listVersions = racine.getChildren("version");
Iterator iteratorVersions = listVersions.iterator();
while(iteratorVersions.hasNext()){
Element version = (Element)iteratorVersions.next();
Element elementNom = version.getChild("nom");
if(elementNom.getText().equals((String)versionChoisie)){
Element elementFiles = version.getChild("files");
List listFiles = elementFiles.getChildren("file");
Iterator iteratorFiles = listFiles.iterator();
while(iteratorFiles.hasNext()){
Element file = (Element)iteratorFiles.next();
downloadFile(file.getChildText("url"),currentFolder +
File.separator + file.getChildText("destination"));
}
break;
}
}
JOptionPane.showMessageDialog(null,"La nouvelle version a été téléchargée, " +
"le programme va être relancé");
File lanceur = new File(lanceurPath);
try {
Desktop.open(lanceur);
System.exit(0);
} catch (DesktopException e) {
JOptionPane.showMessageDialog(null,"Impossible de relancer le programme");
}
}
}
else{
JOptionPane.showMessageDialog(null,"Pas de nouvelles version disponible pour le moment");
}
}
}
|
VI. Conclusion
VI-A. Conclusion
Voilà, vous savez maintenant comment créer un système de mise à jour pour vos programmes. Vous pouvez dès à présent employer votre nouveau savoir dans un de vos programmes, par exemple lors du clic sur un bouton ou un menu.
VI-B. Les sources
Voici les 2 classes que l'on a employées dans ce tutoriel :
Et voici ou vous pouvez télécharger les apis que l'on a utilisées :


Copyright © 2006 Baptiste Wicht . Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts