Java, packages et Madkit

Thomas Petazzoni, thomas point petazzoni chez enix point org

Dans le cadre d'un projet pour l'UV IA54 (Système Multiagents) à l'UTBM, j'ai été amené à modifier Turtlekit, et donc à réaliser des packages Java à faire fonctionner dans MadKit. J'ai éprouvé quelques difficultés à tout faire fonctionner, et je n'ai pas trouvé de documentation complète sur le sujet. Je vais donc expliquer comment j'ai fait, d'une part pour m'en souvenir, d'autre part parce que cela pourra peut être servir à d'autres.

1. Objectif

L'objectif était de modifier TurtleKit et une simulation basée dessus, Hunt. TurtleKit est un ensemble de classes de base permettant de simuler simplement des agents se déplaçant dans un monde bi-dimensionnel représenté par une matrice. La simulation Hunt montre comment des prédateurs essaient d'encercler des proies pour les manger.

Pour modifier TurtleKit et Hunt, nous n'avons pas souhaité les modifier directement dans les sources de MadKit, mais en faire une copie de travail.

2. Comment faire ?

Tout au long du document, $MADKITDIR désigne le répertoire d'installation de MadKit.

2.1 Copie des sources

La première étape est de se créer un répertoire dans lequel on va mettre tout ça, par exemple projet-ia54. On créé ensuite 2 sous répertoires, hunt et turtlekit, qui vont respectivement contenir les classes Java de la simulation Hunt et du noyau TurtleKit.

Ensuite, on copie les sources du TurtleKit depuis $MADKITDIR/src/turtlekit/kernel dans notre répertoire projet-ia54/turtlekit. On recopie également les sources de Hunt depuis $MADKITDIR/src/turtlekit/simulations/hunt vers notre répertoire projet-ia54/hunt.

On doit maintenant avoir les fichiers suivants :

2.2 TurtleKit

Compiler TurtleKit n'est pas facile, car il dépend d'un certain nombre de classes (notamment pas mal de choses qui concernent Python). On a donc besoin dans le Classpath des fichiers suivants :

Pour compiler, la première étape est de changer le nom du package généré. J'ai décidé de l'appeler ia54.turtlekit. Il convient donc, dans chaque fichier .java de TurtleKit, de changer la ligne package turtlekit.kernel; par la ligne package ia54.turtlekit;.

Ensuite, pour compiler, il suffit d'utiliser le Makefile suivant, et de taper make all install :

1.  MADKITDIR=/home/thomas/madkit_3.1b5
2.  MADKITLIBSDIR=$(MADKITDIR)/libs/madkit
3.  CLASSPATH=.:$(MADKITLIBSDIR)/madkit.jar:$(MADKITDIR)/libs/extens/pythonlib.jar:$(MADKITDIR)/libs/support/jython.jar:$(MADKITDIR)/autoload/pythonagents.jar
4.  JAR=ia54.turtlekit.jar
5. 
6.  all: $(JAR)
7. 
8.  $(JAR): classes
9.         jar cvf $@ -C classes/ .
10.
11. classes: *.java
12.        mkdir -p classes
13.        javac -d classes/ -classpath $(CLASSPATH) $^
14.
15. install:
16.        cp $(JAR) $(MADKITDIR)/libs/madkit/
17.
18. clean:
19.        $(RM) -r classes/ *.jar

Quelques explications s'imposent, mais tout d'abord, je précise que je ne suis pas un gourou du Makefile, ni des outils de compilation Java, donc ce n'est sans doute pas optimal.

Après compilation, on se retrouve avec dans le répertoire classes, un répertoire ia54 puis un répertoire turtlekit : l'arborescence correspondant au package ia54.turtlekit a été reproduite. Dans ce répertoire classes/ia54/turtlekit, on trouve toutes les classes compilées. Le fichier Jar généré contient donc toutes ces classes, avec un chemin ia54/turtlekit, ce qui est très important pour que les classes qui importent notre package fonctionnent. Le fichier Jar doit ensuite être copié dans le répertoire libs/madkit, qui est le répertoire des librairies de MadKit. Il ne faut pas le mettre dans le répertoire autoload, car ce répertoire est réservé aux Jar contenants des classes à "lancer" (voir plus bas).

Voilà pour la compilation de notre TurtleKit. Pour l'utiliser, nous allons maintenant compiler et installer Hunt.

2.3 Hunt

Tout d'abord, j'ai retiré les lignes package turtlekit.simulations.hunt; des trois fichiers sources Java. Ensuite, il faut changer la ligne import turtlekit.kernel.Launcher; par import ia54.turtlekit.Launcher; et la ligne import turtlekit.kernel.Turtle; par import ia54.turtlekit.Turtle;. Grâce à cela, nos classes de Hunt utiliseront notre nouveau TurtleKit, et non celui fourni par défaut avec MadKit.

On peut maintenant compiler le tout à l'aide du Makefile suivant :

1.  SRC=Predator.java Prey.java HuntLauncher.java
2.  MANIFEST=manifest
3.  MADKITDIR=/home/thomas/madkit_3.1b5
4.  MADKITLIBSDIR=$(MADKITDIR)/libs/madkit
5.  CLASSPATH=$(MADKITLIBSDIR)/madkit.jar:../turtlekit/ia54.turtlekit.jar:.
6.  JAR=ia54.hunt.jar
7.
8.  all: $(JAR)
9.
10. $(JAR): $(SRC:%.java=%.class)
11.        jar cvfm $@ $(MANIFEST) $^
12.
13. %.class: %.java
14.        javac  -classpath $(CLASSPATH) $<
15.
16. install:
17.        cp $(JAR) $(MADKITDIR)/autoload/
18.
19. clean:
20.        $(RM) *.class *.jar

Pour compiler Hunt, il est nécessaire d'avoir au préalable généré le Jar de TurtleKit. Quelques explications à propos du Makefile

Tout est relativement classique, à l'exception du fichier manifest. Ici il est important d'en spécifier un, car c'est dans ce fichier qu'on indique à MadKit quelles sont les classes qu'on peut "lancer" en cliquant dessus. Dans notre cas, c'est la classe HuntLauncher que l'on souhaite lancer, on a donc le manifest suivant :

1.
2. Name: HuntLauncher.class
3. Agent: True

On indique donc que la classe de nom HuntLauncher.class est l'agent (Agent: True). A noter que la ligne vide au début du manifest est importante. Si je ne la mets pas, lors de la création du Jar, les lignes Name et Agent sont mélangées parmi les lignes ajoutées par la commande jar, et MadKit ne détecte plus quelle est la classe à charger. Vous pouvez vérifier que le manifest de l'archive est correct en l'extrayant. En effet, un Jar est tout simplement un fichier zip. Il suffit de faire unzip ia54.hunt.jar META-INF/MANIFEST.MF pour etraire le fichier dans le répertoire META-INF. Il doit normalement contenir quelque chose comme :

Manifest-Version: 1.0
Created-By: 1.4.1 (Blackdown Java-Linux Team)

Name: HuntLauncher.class
Agent: True

3. Dans MadKit

Maintenant, lors du lancement de MadKit, il devrait y avoir dans le répertoire autoload, un répertoire ia54.hunt.jar, avec à l'intérieur la classe HuntLauncher.

Conclusion

Voilà tout ce que je sais à propos de la création des Jar et de leur utilisation pour MadKit. La documentation n'est certainement pas complète, pas forcément optimale, mais chez moi ça fonctionne. Si vous avez des questions, n'hésitez pas à me contacter : thomas point petazzoni chez enix point org.