|
|||||||||||||||||||||||||||||||||||||||
|
Les plug-ins permettent de modulariser une application. Il est naturellement très fréquent de devoir permettre à un plug-in d'appeler le code contenu dans un autre.
Par défaut chaque plug-in est isolé : il ne peut accéder aux classes des autres plug-ins et les autres plug-ins ne peuvent accéder à ses classes. En modifiant le fichier MANIFEST.MF d'un plug-in, il est possible de rendre accessibles tout ou partie de ses classes. Les autres plug-ins qui souhaitent appeler ces classes accessibles devront l'indiquer explicitement dans leur fichier MANIFEST.MF.
Pour manipuler cette notion de dépendances, nous
allons détailler pas à pas les 3 cas suivants :
- dépendances entre deux plug-ins.
- intégration d'une librairie (fichier JAR) dans un plug-in.
- création d'un plug-in à partir d'une librairie.
Pour tester la notion de dépendance nous allons créér un deuxième plug-in qui sera appelé par le premier :
Création
d'un deuxième plug-in :
- Utiliser l'assistant de création de projet de plug-in pour créer un plug-in nommé 'com.eclipsetotale.tutorial.horloge.texte', conserver les valeurs par défaut pour les différents champs de l'assistant. Dans la page de l'assistant permettant de choisir un modèles ('Templates'), décocher la case à cocher 'Create a plug-in using one of the templates'.
- Une fois le plug-in créé ajouter la classe
suivante dans le plug-in :
(NB: pour créer cette classe la méthode la plus simple est
de sélectionner le code ci-dessous, de le copier, puis dans Eclipse
de sélectionner le répertoire 'src' du projet et
d'utiliser l'option 'Paste' du menu contextuel. De cette façon
Eclipse crée la classe et le package si nécessaire)
|
package com.eclipsetotale.horloge.texte; import
java.text.DateFormat; import
org.eclipse.jface.resource.JFaceResources; public
class HorlogeTexte { public
HorlogeTexte(final Composite parent)
{ heureLabel
= new Label(parent, SWT.CENTER); final
Runnable updateUIRunnable = new Runnable()
{ Thread
thread = new Thread(new
Runnable() { private
Font getFont(Composite parent) { public
void dispose() { } |
Rendre
les classes accessibles par d'autres plug-ins.
Par défaut, la classe précédemment créée ne peut pas être invoquée par un autre plug-in. Conformément à la spécification OSGi, un plug-in doit déclarer explicitement dans le fichier MANIFEST.MF les classes qu'ils souhaitent rendre visibles. La granularité choisie est celle du package, la liste des packages visibles est déclarée via la variable 'Exported-packages' du fichier MANIFEST.MF.
L'éditeur de fichiers manifestes proposés
par le PDE, simplifie la mise à jour du fichier MANIFEST.MF. Pour
'exporter' la classe 'com.eclipsetotale.tutorial.horloge.texte.HorlogeTexte'
suivre les étapes suivantes :
- Ouvrir l'éditeur de fichiers manifestes du plug-in 'com.eclipsetotale.tutorial.horloge.texte'
(double-cliquer sur le fichier META-INF/MANIFEST.MF).
- Sélectionner l'onglet 'Runtime'.
- Utiliser le bouton 'Add...' associé à la section
'Exported packages' pour ajouter le package 'com.eclipsetotale.tutorial.horloge.texte'
à la liste :

Suite à cette opération, le fichier MANIFEST.MF contient la ligne suivante :
|
Export-Package: com.eclipsetotale.tutorial.horloge.texte |
Utiliser
les classes à partir d'un autre plug-in.
Pour que notre premier plug-in puisse appeler la classe
HorlogeTexte du second plug-in, il est nécessaire de déclarer
explicitement dans le fichier MANIFEST.MF du premier plug-in qu'il y a
une dépendance avec le deuxième plug-in.
Les dépendances se déclarent dans l'onglet 'Dependencies'
de l'éditeur de fichier manifestes :

Ce qui équivaut à modifier la ligne suivante du fichier MANIFEST.MF :
|
Require-Bundle:
org.eclipse.ui, |
Une fois cette dépendance déclarée, nous pouvons modifier le code de la classe 'com.eclipsetotale.tutorial.premierplugin.actions.SampleAction' générée lors de la création du premier plug-in. La méthode run(IAction) est celle déclenchée lorsque l'utilisateur sélectionne le menu correspondant. Réimplémenter cette méthode de la façon suivante :
|
public void
run(IAction action) { |
(NB: lors de l'ajout des imports bien sélectionner ceux commençant par 'org.eclipse')
Tester,
une fenêtre affichant l'heure doit s'ouvrir.
La déclaration
d'une dépendance est le moyen privilégié de indiquer
qu'un plug-in souhaite accéder aux classes visibles d'un autre
plug-in. En plus d'autoriser l'accès aux classes du plug-in indiqué
en pré-requis, le noyau d'Eclipse validera que ce plug-in est bien
présent lors de l'exécution et éventuellement choisira
la version du plug-in la plus adaptée (en fonction des règles
indiquées en utilisant le bouton 'Properties' de l'onglet
'Dependencies').
Il existe un autre moyen d'accéder aux classes d'un plug-in sans que ce dernier soit déclaré comme 'Required plug-ins'. Il s'agit de la propriété 'Imported-packages' d'OSGi, accessible dans l'onglet 'Dependencies', elle est rarement utilisée par les plug-ins Eclipse mais elle permet d'assouplir la relation entre deux plug-ins : le plug-in qui importe des packages n'a pas besoin de connaître le nom de celui qui les exportent, la résolution se fait lors de l'exécution (ce qui est peut être problèmatique si aucun plug-in n'exportent les bons packages ou si plusieurs les exportent).
Lors de l'écriture de plug-ins, il est relativement courant de vouloir s'appuyer sur une librairie existante (par exemple proposée par un projet open-source). La première possibilité est d'intégrer directement le fichier JAR dans le plug-in. Etudions ce cas via la création d'un nouveau plug-in utilisant un fichier JAR fourni par le sous-projet Nebula de la fondation Eclipse.
Créer
un nouveau projet de plug-in nommé 'com.eclipsetotale.tutorial.horloge.nebula'
(ne pas utiliser de template).
Télécharger
le fichier JAR suivant : nebula_cdatetime_0.9.0.jar
Créer
un sous-répertoire 'lib' dans le projet et y placer le fichier
JAR.
Pour que
les classes de ce fichiers JAR soient utilisables il faut ajouter le fichier
au 'classpath' du plug-in. L'onglet 'Runtime' de l'éditeur
de fichier manifestes permet de faire cet ajout en utilisant le bouton
'Add' associé à la section 'Classpath' :

La ligne suivante est ajoutée au fichier 'MANIFEST.MF' :
|
Bundle-ClassPath:
lib/nebula_cdatetime_0.9.0.jar, |
Pour tester
la bonne intégration du JAR, ajouter la classe suivante dans le
projet de plug-in.
|
package com.eclipsetotale.tutorial.horloge.nebula; import
java.util.Date; public
class HorlogeNebula { public
HorlogeNebula(final Composite parent)
{ heureCDT
= new CDateTime(parent, CDT.COMPACT
| CDT.BORDER | CDT.SIMPLE
| CDT.TIME_MEDIUM | CDT.CLOCK_12_HOUR); final
Runnable updateUIRunnable = new Runnable()
{ Thread
thread = new Thread(new
Runnable() { } |
Rendre
cette classe visible par les autres plug-ins. Procéder de la même
façon que pour le plug-in 'com.eclipsetotale.tutorial.horloge.texte'
: dans l'onglet 'Runtime', ajouter le package 'com.eclipsetotale.tutorial.horloge.nebula'
dans la section 'Exported packages'.
Ajouter
le plug-in 'com.eclipsetotale.tutorial.horloge.nebula' dans la
liste des plug-ins pré-requis du plug-in 'com.eclipsetotale.tutorial.premierplugin'
(utiliser l'onglet 'Dependencies' de l'éditeur de fichier
manifestes, section 'Required plug-ins').
Modifier
le code de le la classe 'SampleAction' du premier plug-in pour
lui faire utiliser la classe 'HorlogeNebula', voici le code de
la méthode run(IAction) :
|
public void
run(IAction action) { |
Tester,
la fenêtre suivante doit s'ouvrir :

L'intégration de fichiers JAR directement dans les plug-ins pose notamment le problème de la duplication de ces fichiers dans plusieurs plug-ins. Il est donc généralement préférable de créer un plug-in spécifiquement pour chaque librairie et d'utiliser la notion de dépendance pour en donner l'accès aux autres plug-ins.
Eclipse propose un assistant particulier pour automatiser la création d'un plug-in à partir de fichiers JAR. Voici les étapes pour créer un plug-in à partir du fichier JAR précédemment téléchargé.
Créer
un nouveau projet à partir du menu 'File->New->Project...'
en sélectionnant le type 'plug-in from existing JAR archives'
:

Dans la
deuxième page de l'assistant utiliser le bouton 'Add External...'
pour indiquer le fichier JAR :

Dans la
troisième page, indiquer le nom du plug-in et cliquer sur 'Finish'
:

L'assistant
crée le projet de plug-in en récupérant le contenu
du JAR, le fichier MANIFEST.MF est initialisé : les packages contenus
dans le JAR sont automatiquement ajoutés à la liste 'Exported
packages' de l'onglet 'Runtime'. L'assistant ne définit
pas de plug-ins dans la liste 'Required plug-ins' de l'onglet dependencies,
dans notre cas le JAR contient des classes qui font appel à la
librairie SWT d'Eclipse, ajouter le plug-ins 'org.eclipse.swt'
comme pré-requis :

Effectuer
les opération suivantes sur le plug-in 'com.eclipsetotale.tutorial.horloge.nebula'
:
-
supprimer le répertoire lib.
-
dans l'onglet 'Runtime' de l'éditeur du fichier MANIFEST.MF
supprimer le contenu de la section 'Classpath'.
-
dans l'onglet 'Dependencies' ajouter le plug-in 'org.eclipse.nebula.cdatetime'
à la liste des 'Required plug-ins'.
Tester.
Le résultat doit être le même que précédemment,
l'intérêt est de disposer d'un plug-in réutilisable
par d'autres plug-ins sans devoir dupliquer le fichier JAR dans tous les
plug-ins souhaitant utiliser cette librairie.
La notion de plug-in intégrée au framework
Eclipse permet le développement et la livraison d'applications
modulaires. Pour faciliter le développement des plug-ins, Eclipse
propose un outillage complet : le PDE (Plug-ins Development Environment).
Les plug-in sont des fichiers JAR enrichis de deux fichiers manifestes
(plugin.xml et MANIFEST.MF). En exploitant les informations contenus dans
les fichiers manifestes, le noyau d'Eclipse, Equinox, gère le cycle
de vie des plugins et leurs dépendances.
Dans ce premier tutorial, nous avons vu comment le framework Eclipse assurait la modularité, dans un prochain tutorial nous étudierons la notion de point d'extension qui concrétise le deuxième objectif des concepteurs d'Eclipse : l'extensibilité.
(L'auteur de cet article est le concepteur et l'animateur de notre formation 'Développement d'applications Eclipse RCP')
![]()
(c) EclipseTotale - Bruno Leroux - contact(arobase)eclipsetotale.com
|
Mots-clés
|
|
Téléchargements
|
|
Télécharger Eclipse RAD 7.0 Plugin |