mardi 2 juin 2015

JavaFX : quelques outils d'aide / support au développement

Dans l'éco-système Java, il y a les outils de développement mais aussi des outils complémentaires très utiles pour les développeurs.

JIRA est un système de suivi de bugs, un système de gestion des incidents et un système de gestion de projets développé par Atlassian Software Systems.

Par exemple vous trouverez les bugs et incidents liés aux versions actuelles du JDK JavaFX.

Encore plus intéressant, vous pouvez déclarer un incident - incident pris en charge par un membre de l'équipe JDK.

L'incident recevra un niveau de priorité.

Une fois l'incident déclaré, vous pouvez suivre le traitement de cet incident et connaître la version future du JDK qui fixera le problème (si toutefois votre problème peut être résolu).

Soyez précis lors de la déclaration d'un incident : le membre de l'équipe JDK doit pouvoir reproduire le problème facilement.

Etant donné que le JDK JavaFX est toujours en version EA, de nombreux bugs sont encore en cours.

Cet outil est donc utile et vous servira de "dashboard" global sur le taux de traitement des problèmes liés au JDK.

OpenJDK est une espace collaboratif à la fois pour l'implémentation Open Source de Java et pour l'implémentation de projets autour de la plateforme Java.

Le JDK JavaFX est issu de projets gérés sur cet espace.

Très intéressant : vous avez la ROADMAP des versions actuelles et futures du JDK - information non négligeable à prendre en considération dans votre planning de développement.

La difficulté d'un projet JavaFX est de pouvoir assoir ce projet sur une version stable du JDK JavaFX.

D'autre part la version choisie doit correspondre aux besoins de votre projet.

Nous sommes aussi dans une transition entre le JDK 8 et le prochain JDK 9 : les API sont (et vont être) modifiées et améliorées.

Quelle version faut-il prendre en compte pour notre projet ?

Autant de questions qu'il faut se poser rapidement.

Windows 10 pour bientôt !

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.