Utiliser la librairie Yoctopuce avec les modules Java

Utiliser la librairie Yoctopuce avec les modules Java

Récemment, un client nous a demandé si notre libraire Java était compatible avec Java 11. La réponse est oui. Nous faisons toujours attention d'être compatible avec les versions actuelles, tout en maintenant la compatibilité ascendante. En l’occurrence, notre librairie est utilisable avec toutes les versions de Java depuis la version 6. Toutefois, Java 9 a introduit Java Platform Module System (aka JPMS ou Project Jigsaw) et, comme nous allons le voir, pour utiliser notre librairie avec les modules Java il y a quelques étapes supplémentaires.

Java est un langage de programmation assez vieux mais qui continue d'évoluer. La plupart des évolutions de ces dernières années maintenait la compatibilité ascendante et n'ajoutait que des fonctionnalités mineures au langage que l'on était libre d'utiliser ou pas. Depuis Java 9, il est possible d'utiliser Java Platform Module System (JPMS). Une fonctionnalité qui change radicalement la manière dont les classes sont distribuées dans un fichier .jar.

L'objectif de JPMS est de pouvoir générer des librairies compilées au format .jar mais en contrôlant plus finement les classes Java qui doivent être chargées lors de l’exécution de l'application. L'idée est de générer plus de petits fichiers .jar au lieu d'un gros fichier monolithique. A terme, cela permet de créer des exécutables plus petits en incluant uniquement ce qui est nécessaire. Mais cela permet aussi de contrôler plus finement les classes qui sont publiées dans un fichier .jar.

Un module Java est composé du code Java et d'un fichier module-info.java. Ce fichier permet de définir le nom du module, les classes et/ou packages qui sont publiés par ce module, et les modules dont il dépend.

Par exemple, voici la déclaration d'un module helloworld qui publie le package com.mycompagny.mypackage et qui a besoin d'un module anothermodule pour fonctionner.

module helloworld {
    exports com.mycompany.mypackage;
    requires anothermodule;
}



Si un autre module veut utiliser le package com.mycompagny.mypackage, il faudra qu'il ajoute requires helloworld; dans son fichier module-info.java.

module mainmodule {
    requires helloworld;
}



Grâce à ce fichier, Java peut résoudre l'arbre de dépendance et vérifier immédiatement si toutes les classes sont disponibles. Le code source Java n'évolue pas, il faut toujours importer les packages que l'on veut utiliser à l'aide du mot-clef "import".

Pour résumer, Java Platform Module System permet de contrôler bien plus finement quelles classes sont chargées par la VM Java.


Dans cet article, nous allons nous concentrer sur ce que cela implique au sujet l'utilisation de notre librairie avec les modules. Si vous désirez en savoir plus sur le fonctionnement de Java Platform Module System, vous pouvez consulter la page Wikipedia ou Internet.


Utiliser la librairie Yoctopuce avec Java >= 9


Il existe trois manières d'utiliser notre librairie dans une application Java:

  1. Ajouter les fichiers sources
  2. Ajouter la version compilée de notre librairie dans le Classpath
  3. Ajouter la version compilée de notre librairie dans le Module-path



Option 1: Ajouter les fichiers sources


C'est la solution la plus simple: Il suffit de copier tous les fichiers Java dans votre projet.

Cette solution permet de contrôler complètement comment utiliser la librairie. Il est possible de la placer dans un module séparé, ou directement dans votre application. Comme le code n'utilise pas de nouvelle fonctionnalité, il est utilisable avec toutes les versions de Java depuis la 6. Et en bonus, les symboles sont disponibles dans votre débuggger/IDE.

Nous fournissons le code source de la librairie Java sur notre site Web ou sur GitHub. C'est la solution que nous recommandons, car quelque soit votre version de Java ou votre système de build notre librairie fonctionnera.


Option 2: Utiliser le fichier yoctoAPI.jar sans JPMS


Même si JPMS a été introduit dans Java 9, il est toujours possible d'utiliser le Classpath comme en Java 6, 7 ou 8. Dans ce cas, il faut simplement ajouter le fichier yoctoAPI.jar dans le Classpath.

Le fichier yoctoAPI.jar est la version précompilée de notre librairie. Il est inclus dans le sous-répertoire Binaries de notre librairie.

Pour ajouter ce fichier .jar au Classpath, il faut utiliser l'option -cp et ajouter le chemin du fichier .jar.

Voici par exemple les commandes pour compiler et exécuter une application Java qui utilise la librairie Yoctopuce:

javac -d outDir -cp ../YoctoLib.java.40924/Binaries/yoctoAPI.jar src/com/mycompany/app/App.java java -cp ../YoctoLib.java.40924/Binaries/yoctoAPI.jar:outDir com.mycompany.app.App



Pour ces deux commandes, on ajoute le fichier ../YoctoLib.java.40924/Binaries/yoctoAPI.jar au
Classpath à l'aide de l'option -cp. Notez qu'il est possible de passer plusieurs paths en les séparant par le caractère : sous Unix et ; sous Windows.


Option 3: Utiliser le fichier yoctoAPI.jar avec JPMS


Pour utiliser la version précompilée de notre libraire dans un projet qui utilise des modules Java, c'est un tout petit peu plus compliqué.

Tout d'abord, précisons que pour des raisons de compatibilité ascendante, notre fichier yoctoAPI.jar n'est pas un module Java. Il s’agit d'un traditionnel fichier .jar sans module-info. Il y a cependant un moyen de l'utiliser dans un projet JPMS.

Il faut d'abord ajouter le fichier yoctoAPI.jar au Module-path à l'aide de l'option --module-path. Comme il ne s'agit pas d'un véritable module, la JVM va l'ajouter comme un "unnamed module" et va lui attribuer un nom en se basant sur le nom du fichier .jar en suivant les règles suivantes:

  • l’extension de fichier ".jar" est ignorée
  • les numéros de versions sont supprimés (Ex: myjar-1.2.3 -> myjar)
  • les caractères non alphanumériques sont replacés par des points


Dans notre cas, notre librairie "yoctoAPI.jar" devient donc le module "yoctoAPI".

Pour finir, il faut ajouter la ligne "require yoctoAPI;" dans le fichier module-info.java du module qui utilise notre librairie.

Par exemple, pour une application composée de deux modules main.app et another.module dont le module another.module utilise notre librairie, il faut ajouter la ligne "require" uniquement au module another.module:

module another.module { requires yoctoAPI; }



Lors de l’exécution, la JVM va parcourir l'arbre des dépendances et déterminer qu'il faut charger notre librairie.


Voici les commandes pour compiler et exécuter ces deux modules.

javac -d outDir --module-source-path Sources Sources/main.app/com/mycompany/app/App.java javac -d outDir --module-source-path Sources --module-path ../YoctoLib.java.40924/Binaries/yoctoAPI.jar Sources/another.module/com/mycompany/module/MyModule.java java --module-path outDir:../YoctoLib.java.40924/Binaries/yoctoAPI.jar -m main.app/com.mycompany.app.App


Comme on peut le voir, c'est très similaire à l'utilisation du Classpath. Il faut simplement utiliser l'option --module-path au lieu de l'option -cp. Notez qu'il est aussi possible de passer plusieurs path à l'option --module-path en les séparant par le caractère : sous Unix et ; sous Windows.

GitHub


Vous pouvez trouver sur GitHub le code source de ces deux exemples:https://github.com/yoctopuce-examples/JPMS_examples

Dans le sous-répertoire my-app-classpath, il s'agit de la version de l'application qui n'utilise pas JPMS, et dans le sous-répertoire my-app-modulepath il s'agit de la même application mais implémentée en utilisant deux modules Java.


Conclusion


Notre librairie est donc compatible avec toutes les versions de Java depuis Java 6. Pour les versions de Java qui le supporte, il est possible d'utiliser notre libraire dans des projets qui utilisent les modules Java.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.