En fait il existe deux moyens de le faire :
- Lancer le programme depuis EasyAnt
- Rendre l'application exécutable en dehors d'EasyAnt, en modifiant le MANIFEST.MF
La première configure EasyAnt pour lancer l'application lors de l'appel d'une target spécifique (:run)
La seconde permet de rendre l'application exécutable en "double cliquant" sur le jar.
Les deux solutions ne sont pas incompatible.
Lancer une main class depuis easyant
Pour lancer une mainclass depuis easyant il est possible d'utiliser le plugin "run-java".
<ea:plugin organisation="org.apache.easyant.plugins" module="run-java" revision="0.1" as="run" />
Le plugin run-java est un plugin fournis et écrit par easyant, il possède donc la même organisation que les autres plugins. En effet tout les plugins easyant utilise l'organisation "org.apache.easyant.plugins". Cette information est optionnel, nous aurions donc pu laissez easyant utiliser la valeur par défaut et écrire :
<ea:plugin module="manifest" revision="0.1" as="run" />
La documentation du plugin nous précise qu'il existe qu'une target (:run) qui n'est attaché à aucune phase.
Je reconnait que l'information ne saute pas au yeux. Nous sommes cependant preneur de toutes idées pour rendre l'information plus accessible
Il faut donc la lancer explicitement a la ligne de commande
En éxécutant la commande, easyant nous préviens que nous avons oublié de renseigner un paramètre du plugin (une property).
Missing value for property run.main.classname
Même si le nom peut paraitre explicite, il est toujours utile de se reporté a la documentation pour savoir a quoi correspond cette property, si elle est obligatoire, si elle à une valeur par défaut, etc..
Donc il faut toujours avoir la documentation d'ouverte ?
Pas forcément, il y'a un petit système d'aide en ligne qui peut s'avérer utile.
Pourquoi pas ne pas demander a easyant à quoi sert cette property :
easyant -describe run.main.classname
Project Manual
--------------
--- Available references for: run.main.classname in current project: standard-java-app ---
No Phase found for name: run.main.classname
No Target found for name: run.main.classname
Property: run.main.classname
Description: name of the main class to run
Default: NONE
Required: true
--- End of (Describe) ---
Ici, EasyAnt nous indique que l'argument fournis, n'est ni une phase, ni une target. C'est une property. Il nous explique que cette property est obligatoire, et nous donne une description.
Ceci fonctionne aussi avec les targets / phase (cf ManCommand).
Que faire une fois qu'on connait les paramètres à utiliser ?
Il suffit de renseigner le paramètre :
- Soit a la ligne de commande pour un besoin ponctuel :
easyant -Drun.main.classname=org.mycompany.MyClass
- Soit en modifiant le module.ivy
<ea:property name="run.main.classname" value="org.mycompany.MyClass"/>
Rendre l'application exécutable en dehors d'EasyAnt, en modifiant le MANIFEST.MF
Comme tu l'as souligné, il est possible d'utiliser le plugin manifest.
Il contient en effet des paramètres optionnel permettant de spécifier la mainclass :
- manifest.main.classname : la main class
- manifest.classpath : le classpath utiliser pour exécuter l'application
La property "manifest.classpath" est automatiquement rempli avec les dépendances présente dans le projet. Cependant il est primordial de forcer easyant à récupérer les dépendances dans un répertoire local dans le projet (j'expliquerait un peu plus bas pourquoi).
Pour cela il faut placer la property "retrieve.dependencies" à true.
Cette fonctionnalité à récemment été introduite , néanmoins je constate (hormis le détail de présentation) qu'il y a un sérieux manque de documentation sur le fonctionnement interne de cette target.
Comment l'utiliser ?
Il n'est pas nécessaire de le déclarer en tant que plugin car il fait partie des plugins inclue par la plus part des buildtypes.
J'imagine que dans ton projet tu utilise le build type "build-std-java".
Donc si on regarde la documentation , on constate qu'il s'appuie bien sur le plugin manifest.
Il suffit de renseigner les paramètres :
- Soit a la ligne de commande pour un besoin ponctuel :
easyant -Dmanifest.main.classname=org.mycompany.MyClass -Dretrieve.dependencies=true
- Soit en modifiant le module.ivy
<ea:property name="manifest.main.classname" value="org.mycompany.MyClass"/>
<ea:property name="retrieve.dependencies" value="true"/>
La documentation nous dis (encore une foi pas très explicitement) que le plugin contient une target (nommé :manifest-runnable) qui ajoute les attribue nécessaire pour rendre l'application exécutable.
Cette target fait partie intégrante du cycle de vie du projet puisqu'elle est rajouter à la phase "prepare-package".
Ainsi lorsque tu lancera
ou n'importe quel autre target qui dépend de "package", le jar généré contiendra les informations nécessaire pour rendre l'application exécutable dans le fichier MANIFEST.MF.
L'application sera donc exécutable sans utiliser EasyAnt.
En attendant de compléter la documentation (dans la prochaine version) voici l'explication :
Pour rendre l'application exécutable, dans certain cas il est nécessaire de référencer les dépendances dans le manifest.
Ainsi si ton projet à une petite dizaine de dépendances tu devrais les référencer dans la property "manifest.classpath".
Pour éviter cette opération fastidieuse, EasyAnt fournis un moyen de remplir cette property automatiquement en se basant sur les dépendances présente dans le module.ivy.
A quoi peut donc servir la property "retrieve.dependencies"?
Par défaut EasyAnt télécharge les dépendances et les places dans un cache (le cache par défaut se trouve dans $USER_HOME/.project/cache/).
Mais il faut savoir que le référencement du classpath dans le MANIFEST.MF est relatif à la position du jar.
Ainsi si ton projet dépend de foobar.jar la variable Class-Path dans le manifest devrait pointer dessus.
Class-Path: /path/to/foobar.jar
Et la c'est le drame ! Comment distribuer l'application et toutes ces dépendances ?
En effet, si on dois distribuer une application on aimerait que les dépendances soit centralisé (et pas cacher dans le cache d'easyant).
Heuresement, EasyAnt nous empêche d'utiliser cette fonctionnalité si la property "retrieve.dependencies" n'est pas égale à "true".
Cette property force easyant à récupéré les dépendances dans un sous répertoire du projet (par défaut dans le répertoire lib/main).
Ainsi nos références dans le fichier manifest devrais être relative à l'arborescence du projet et donc ressembler à
Class-Path: lib/main/foobar.jar
.
N'hésite pas à écrire sur la mailing list si tu as d'autres questions, ou simplement des idées pour simplifier l'utilisation d'EasyAnt.
Partager