février
2009
Maintenant que nous avons vu en détails les caractéristiques des modules, nous allons voir comment mettre en oeuvre un module.
Il nous faut donc un conteneur pour notre module qu’on puisse ensuite charger depuis notre application principale.
Nous allons maintenant voir ce que sera un module au niveau Java.
Comme un module est complètement indépendant de l’application principale, on ne peut inclure directement le module dans l’application principale, il faut distinguer le fichier du module de celui de l’application principale.
Il faut maintenant définir ce que vont être ces fichiers. Comme est au niveau Java, on peut s’imaginer les modules comme des extensions de l’application principale. Or pour étendre une application Java, on utilise des fichiers Jars.
Nos modules seront donc contenus dans des fichiers Jars.
Voici pour ce qui est de la manière de représenter physiquement un module, nous allons voir comment le représenter pour qu’il soit utilisable au niveau Java.
Nous allons donc créer une interface permet de décrire les caractèristiques principales d’un module. Nous allons rester simple pour le moment. Un module doit tout d’abord être rattachable et ensuite détachable. C’est-à-dire le moment ou il va se rattacher à l’application, c’est-à-dire l’étendre et le moment où il va se détacher de l’application. En plus de cela, un module a aussi un nom. Pour le moment, ce sera tout ce dont on a besoin.
On va donc avoir une interface tout simple décrivant notre module :
public void plug();
public void unplug();
public String getName();
}
On pourrait donc créer un module très simple affichant quelque chose sur la console :
public class SimpleModule implements IModule {
public void plug(){
System.out.println("Hello kernel !");
}
public void unplug(){
System.out.println("Bye kernel !");
}
public String getName(){
return "Simple module";
}
}
Nous allons donc créer un fichier Jar contenant notre classe.
Il faut maintenant une solution pour que l’application principale connaisse cette classe pour la lancer. Il faut donc un moyen pour qu’elle trouve cette classe.
On pourrait imaginer parcourir le fichier jar et tester pour chacun des classes si c’est un module ou non. Cette méthode bien que fonctionnelle n’est pas du tout optimale car elle implique de parcourir toute l’archive ce qui risque de prendre du temps dans le cas de gros module. Alors, on va utiliser les outils que nous offre Java et ajouter une mention dans le manifest du jar pour indiquer à l’application principale quelle est la classe du module à charger.
Voilà à quoi ressemblerait notre Manifest pour notre petit module :
Module-Class: org.modules.simple.SimpleModule
Cela permettra à l’application principale de savoir quelle classe charger.
Je montrerai dans mon prochain billet une manière de charger ces modules. Car il ne suffit pas de mettre ces fichiers jars dans le classpath pour les charger étant donné que l’application principale ne doit pas connaître les modules.
10 Commentaires + Ajouter un commentaire
Archives
- novembre 2011
- avril 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- juillet 2009
- juin 2009
- avril 2009
- mars 2009
- février 2009
- octobre 2008
- septembre 2008
- mars 2008
- février 2008
- janvier 2008
- décembre 2007
- novembre 2007
- octobre 2007
- septembre 2007
- août 2007
- juillet 2007
- juin 2007
- mai 2007
- avril 2007
Catégories
- AMD
- Apple
- Cartes graphiques
- Chrome
- Conception
- Divers
- Eclipse
- English
- Hardware
- Informatique générale
- Intégration continue
- IntelliJ Idea
- Java
- JTheque
- Linux
- Logiciels
- Mes articles
- Mes critiques de livres
- Mes projets
- Microsoft
- Mon serveur perso
- Office 2007
- Open Source
- Outils
- Perso
- PHP
- Processeurs
- Programmation
- Sécurité
- Spring
- Windows Vista
- Windows XP
Je pense que benwit parle de l’intégration des plugins avec l’application.
Ici on a affaire à des plugins totalement séparés de l’application, mais on pourrait très bien fournir au plugins une référence vers une instance d’utilitaire permettant de la lier plus fortement à l’application
a++
Je suis toujours pas sûr d’avoir bien compris :aie:
Bien entendu, les modules peuvent intégrer leur propre configuration dans le jar, ce qui est normal car on peut effectivement voir un module comme une application. Néanmnoins, cette configuration peut-être chargée depuis les services de l’application. Au niveau de la configuration propre, c’est à dire des propriétés, les modules peuvent enregistrer des états via un service du coeur de l’application et cet état est ensuite enregistré par l’application principale.
Je pense qu’en général, toute application a besoin d’être configurée (accès aux ressources, …).
Si un module est une application, est ce qu’il intégre sa propre configuration via des fichiers dans son jar ?
Ou est-ce que l’accès aux ressources se fait via les services de l’application ?
Dans ce cas, c’est l’application qui est configurée.
benwit : J’ai pas vraiment compris ta question
Pour le moment, on a effectivement un seul module par jar. La classe du module (implémentant IMOdule) est renseignée dans le manifest du Jar et le loader charge cette classe. Par contre, en plus de la classe du module, il peut y avoir n’importe quoi dans le fichier Jar.
Le fait d’avoir des modules jar, c’est bien mais comment chacun de ces modules est configuré ?
Un fichier dans chacun des jars ?
avec ce genre d’approche, et un networkClassLoader, y’a moyen de s’amuser un moment je pense
Merci Hikage, mais je connaissais déja OSGI
Néanmoins, j’ai vraiment découvert OSGI seulement après avoir commencé mon système de modules et je ne voulais pas recommencer. De plus, certains concepts ne me convenaient pas tout à fait et l’idée de tout refaire depuis le début me motivait bien
A titre d’information ( car un peu plus complexe à mettre en place ), OSGi propose un moyen de faire cela aussi.
En gros, lorsque tu charge un Bundle ‘plugin’ dans le conteneur, celui-ci aura la possibilité d’enregistrer un ‘service’.
Ce service doit posséder une interface ( IModule dans ton exemple ).
Ton application principale, elle aussi un Bundle Osgi, pourra quand à elle s’enregistrer sur différents évènements, entre autre le chargement et le déchargement des services de type IModule.class.
Et donc gérer dynamiquement les plugins
Bon, c’est clairement plus complexe que ta proposition, mais c’est intéressant de le savoir quand même je pense
Salut,
C’est intéressant comme fonctionnalité
Je ne connaissais pas du tout
Je pense que je vais rester sur ma technique pour le moment étant donné qu’elle me suffit, mais ça peut être très intéressant.
A+
Salut !
A noter que Java 6 intègre la notion de « service » déjà utilisé en interne par Sun.
Cela permet de déclarer simplement des classes implémentant une certaine interface (ou héritant d’une certaine classe).
Pour cela c’est assez simple : il suffit de créer dans le répertoire
du jar un fichier texte (UTF8) du nom complet de l’interface. Par exemple si le nom complet de ton interface est
, ton jar devra comporter un fichier nommé
.
Ce fichier doit simplement contenir les noms des classes concrêtes qui implémentent l’interface. Donc dans ton cas :
Tu peux bien sûr définir plusieurs classes (une par ligne), et utiliser des commentaires (avec #).
Il suffit ensuite d’utiliser la classe
pour rechercher et instancier toutes les classes correspondantes dans le classloader:
Bien sûr si tu as plusieurs fichiers de services identiques dans plusieurs jar, ils seront tous lu et interpréter
Cela n’existe pas sous Java 5.0 et inférieur, mais c’est très facilement réalisable en jouant avec les classloader et l’API de reflection. Un exemple dans cette discussion :
http://www.developpez.net/forums/d227725/java/general-java/apis/reflexion-connaitre-toutes-classes-impl-mentent-interface/
a++