mardi 2 juin 2015

JavaFx : Runtime / Jar

Pour tester votre application, vous exécutez (par exemple sous Eclipse) votre application (en mode Runtime).

Les tests sont positifs, donc tout va bien.

Vous packagez (génération du fichier Jar) votre application avec succès.

Quelque fois dans l'euphorie ou la précipitation un test est oublié :  le test après Packaging de l'application.

Nous partons souvent du principe que puisque les tests sont corrects en mode Runtime forcément ils seront corrects en mode Packaging !

Si cela est le cas, nous faisons une grosse erreur : l'application doit être testée dans les deux modes.

Cette erreur peut amener son lot de problèmes.


Prenons un exemple concret pour illustrer.

Dans toute application, il y a très souvent des accès à des ressources (par exemple : lire un fichier XML ou lire un fichier IMAGE).

Selon le contexte (et les fonctions utilisées) certaines ressources sont accessibles d'une certaine façon en mode Runtime et d'une autre en mode Packaging.

Exemple :

En mode Runtime

public static final String FOP_CONFIGURATION_FILE = "mycfg.xml";

String config = MyClasse.class
.getResource(FOP_CONFIGURATION_FILE).toString()
.substring(6); (*)

fopFactory.setUserConfig(new File(config));

(*) un <substring(6)> est nécessaire car nous obtenons : file:/D:/..../mycfg.xml (chemin absolu dans le file system) : il faut donc supprimer le préfixe "file:/"

Dans cet exemple nous accédons à un fichier de configuration nécessaire pour initialiser le moteur "XSL:FO" (transformer des données XML - par exemple générer un fichier PDF à partir de ces données).

Le fichier FOP_CONFIGURATION_FILE se trouve dans le même package Java que la classe MyClasse.

En mode Runtime, le même package = le même répertoire.

En mode Packaging (lors de l'exécution du Jar)

fopFactory.setUserConfig(this.getClass()
.getResource(FOP_CONFIGURATION_FILE).toURI().toString());

Dans ce cas il faut transformer le chemin de notre fichier en URI pour initialiser notre moteur XSL.


Nous avons donc deux approches très proches mais différentes pour accèder à une même ressource.

Quelle est donc la bonne pratique pour être sûr que le code de notre exemple s'exécute correctement dans les deux modes d'exécution ?

if (MyClasse.class.getResource(FOP_CONFIGURATION_FILE)
.toString().contains("jar:")) {
        // accès en mode Packaging
fopFactory.setUserConfig(this.getClass()
.getResource(FOP_CONFIGURATION_FILE).toURI().toString());

} else {
// accès en mode Runtime
String config = MyClasse.class
.getResource(FOP_CONFIGURATION_FILE).toString()
.substring(6);

fopFactory.setUserConfig(new File(config));
}

Si la valeur retournée par la fonction <getResource> contient "jar:" alors nous sommes en mode Packaging sinon nous sommes en mode Runtime.

Vous avez notez qu'une ressource qui se trouve dans le Jar n'est pas un fichier au sens strict : c'est une "composante" d'un fichier Jar.


Cet exemple a servi à illustrer l'importance de tester tous les comportements (notamment les accès aux ressources) de votre application qu'elle soit en mode DEV ou en mode PRODUCTION.

Il faudra peut être isoler les cas qui vont nécessiter un traitement particulier en mode Runtime ou en mode Packaging.

Aucun commentaire:

Enregistrer un commentaire