<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://air.imag.fr/index.php?action=history&amp;feed=atom&amp;title=TAGL%2FTP_2015</id>
	<title>TAGL/TP 2015 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://air.imag.fr/index.php?action=history&amp;feed=atom&amp;title=TAGL%2FTP_2015"/>
	<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP_2015&amp;action=history"/>
	<updated>2026-06-10T18:56:29Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP_2015&amp;diff=23574&amp;oldid=prev</id>
		<title>Donsez: Created page with &quot;Travaux pratiques de l&#039;UE TAGL.  Anciennes versions : TAGL/TP 2014 =Séance 1 : Gestion de versions= ==Git==  Création d&#039;un dépôt Git local  ===Méthode simple: ini...&quot;</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP_2015&amp;diff=23574&amp;oldid=prev"/>
		<updated>2015-09-01T09:36:12Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;Travaux pratiques de l&amp;#039;UE &lt;a href=&quot;/index.php/TAGL&quot; title=&quot;TAGL&quot;&gt;TAGL&lt;/a&gt;.  Anciennes versions : &lt;a href=&quot;/index.php/TAGL/TP_2014&quot; title=&quot;TAGL/TP 2014&quot;&gt;TAGL/TP 2014&lt;/a&gt; =Séance 1 : Gestion de versions= ==Git==  Création d&amp;#039;un dépôt Git local  ===Méthode simple: ini...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Travaux pratiques de l&amp;#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
Anciennes versions : [[TAGL/TP 2014]]&lt;br /&gt;
=Séance 1 : Gestion de versions=&lt;br /&gt;
==Git==&lt;br /&gt;
&lt;br /&gt;
Création d&amp;#039;un dépôt Git local&lt;br /&gt;
&lt;br /&gt;
===Méthode simple: init first===&lt;br /&gt;
&lt;br /&gt;
Via cette méthode, on crée un dépôt local, avec un répertoire de travail, puis on pousse ses modifications vers un dépôt &amp;quot;bare&amp;quot;.&lt;br /&gt;
Cette méthode est la plus simple, car on dispose immédiatement d&amp;#039;un répertoire de travail.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Création d&amp;#039;un dépôt Git dans le dossier simple-repo&lt;br /&gt;
git init simple-repo&lt;br /&gt;
&lt;br /&gt;
# Création d&amp;#039;un README&lt;br /&gt;
cd simple-repo&lt;br /&gt;
echo &amp;quot;Hello, World&amp;quot; &amp;gt; README&lt;br /&gt;
&lt;br /&gt;
# Ajout du versionnement du fichier README&lt;br /&gt;
git add README&lt;br /&gt;
&lt;br /&gt;
# Commit&lt;br /&gt;
git commit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À ce niveau, on a un dépôt Git complètement fonctionnel.&lt;br /&gt;
Cependant, il est intéressant de pousser ses modifications vers un autre dépôt, sur une autre machine.&lt;br /&gt;
On va donc créer un dépôt bare sur une autre machine (ou autre dossier pour l&amp;#039;exemple)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git init --bare server-repo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On considère que l&amp;#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&amp;#039;abord ajouter ce dépôt serveur à la liste des dépôts connu-repos de votre dépôt local.&lt;br /&gt;
Étant donné qu&amp;#039;il s&amp;#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&amp;#039;appellera //origin//, par convention.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git remote add origin URL_REPO&lt;br /&gt;
# Récupération de ses informations&lt;br /&gt;
git fetch origin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce serveur distant est &amp;quot;vide&amp;quot;: il n&amp;#039;a aucune branche. On va donc enregistrer notre branche sur le serveur&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git push origin master&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
À partir de cette commande, la branche locale //master// sera liée à la branche distante //origin/master//.&lt;br /&gt;
Lors des prochaines commandes &amp;#039;&amp;#039;git push&amp;#039;&amp;#039;, grâce à cette liaison, tous les commits sur la branche locale //master// seront poussées sur le serveur distant.&lt;br /&gt;
&lt;br /&gt;
===Méthode moins simple: bare first===&lt;br /&gt;
&lt;br /&gt;
Si on commence dans par le serveur &amp;quot;vide&amp;quot;, il faudra le cloner au lieu de le définir comme un dépôt distant.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Création du dépôt vide&lt;br /&gt;
git init --bare server-repo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On considère que ce dépôt est accessible à l&amp;#039;URL URL_REPO&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Clonage du dépôt&lt;br /&gt;
git clone URL_REPO clone-repo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un avertissement indique que l&amp;#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&amp;#039;est pas liée au dépôt distant, car celui-ci n&amp;#039;a aucune branche.&lt;br /&gt;
Le dépôt distant est automatiquement appelé //origin//.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Commit dans le dépôt local&lt;br /&gt;
cd clone-repo&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit et ses dépendances&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Comme dans la méthode simple, il faut pousser la branche master vers le dépôt distant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git push origin master&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===De l&amp;#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&amp;#039;avoir au moins 2 fichiers dans votre dépôt Git:&lt;br /&gt;
&lt;br /&gt;
* LICENSE: contenant le texte **complet** de la licence de votre projet&lt;br /&gt;
* README: décrivant votre projet et comment l&amp;#039;utiliser. Ce fichier doit rappeler le nom de la licence de votre projet&lt;br /&gt;
&lt;br /&gt;
Il est aussi recommandé d&amp;#039;avoir les fichiers suivants:&lt;br /&gt;
&lt;br /&gt;
* AUTHORS: contenant la liste des noms/pseudos et e-mails des auteurs de commits ou de code inclus dans ce projet&lt;br /&gt;
* INSTALL: contenant la liste des dépendances de ce projet et des commandes à utiliser pour le compiler et l&amp;#039;installer&lt;br /&gt;
&lt;br /&gt;
Les fichiers LICENSE sont des fichiers textes bruts.&lt;br /&gt;
Les autres fichiers sont généralement dans un format offrant un peu plus de lisibilté, par exemple dans les formats [http://daringfireball.net/projects/markdown/ Markdown] (.md) ou [http://docutils.sourceforge.net/rst.html reStructuredText] (.rst)&lt;br /&gt;
&lt;br /&gt;
Un plug-in existe pour éditer des fichier reStructuredText dans Eclipse: ReST Editor, disponible sur le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
=Séance 2a: Intégration en continue=&lt;br /&gt;
&lt;br /&gt;
===GitHub &amp;amp; [[Travis-CI]]===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&amp;#039;exécuter un script dans une machine virtuelle Ubuntu dès que vous effectuez un push sur un de vos dépôts GitHub.&lt;br /&gt;
L&amp;#039;intérêt est de savoir si la version d&amp;#039;un projet que vous avez rendu publique peut être compilée et si ses tests passent.&lt;br /&gt;
&lt;br /&gt;
La machine virtuelle &amp;quot;offerte&amp;quot; par Travis est préconfigurée pour le language indiqué dans son fichier de configuration (&amp;#039;&amp;#039;&amp;#039;.travis.yml&amp;#039;&amp;#039;&amp;#039;), mais il est possible d&amp;#039;utiliser la commande &amp;#039;&amp;#039;&amp;#039;sudo apt-get install ...&amp;#039;&amp;#039;&amp;#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour utiliser [[Travis-CI]]:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &amp;#039;&amp;#039;Fork&amp;#039;&amp;#039;ez le dépôt https://github.com/heroku/node-js-getting-started&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &amp;#039;&amp;#039;forké&amp;#039;&amp;#039;, via les paramètres (&amp;#039;&amp;#039;settings&amp;#039;&amp;#039;) de ce projet&lt;br /&gt;
# Pour l&amp;#039;exemple, activez le service (ou hook) &amp;#039;&amp;#039;Email&amp;#039;&amp;#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &amp;#039;&amp;#039;&amp;#039;git push&amp;#039;&amp;#039;&amp;#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&amp;#039;&amp;#039;sign in&amp;#039;&amp;#039;) sur https://travis-ci.org/ avec votre compte GitHub&lt;br /&gt;
# Activez le service pour les projets sur lesquels vous souhaitez appliquer les principes d&amp;#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
[[Travis-CI]] utilise un fichier nommé &amp;#039;&amp;#039;&amp;#039;.travis.yml&amp;#039;&amp;#039;&amp;#039; (attention: fichier caché sous Unix) pour se configurer et choisir les opérations à effectuer.&lt;br /&gt;
Ce fichier doit se trouver à la racine de votre dépôt Git.&lt;br /&gt;
&lt;br /&gt;
Faites un &amp;#039;&amp;#039;&amp;#039;Commit&amp;#039;&amp;#039;&amp;#039; puis un &amp;#039;&amp;#039;&amp;#039;Push&amp;#039;&amp;#039;&amp;#039; du fichier &amp;#039;&amp;#039;&amp;#039;.travis.yml&amp;#039;&amp;#039;&amp;#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: node_js&lt;br /&gt;
node_js:&lt;br /&gt;
  - &amp;quot;0.11&amp;quot;&lt;br /&gt;
  - &amp;quot;0.10&amp;quot;&lt;br /&gt;
  - &amp;quot;0.8&amp;quot;&lt;br /&gt;
  - &amp;quot;0.6&amp;quot;&lt;br /&gt;
  - iojs&lt;br /&gt;
  - iojs-v1.0.2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ce fichier &amp;#039;&amp;#039;&amp;#039;.travis.yml&amp;#039;&amp;#039;&amp;#039; indique à [[Travis-CI]] que les scripts de ce projet dans ce dépôt seront exécutés avec plusieurs versions de [[Node.js]].&lt;br /&gt;
&lt;br /&gt;
Ajoutez dans le fichier &amp;#039;&amp;#039;&amp;#039;package.json&amp;#039;&amp;#039;&amp;#039; la section suivante:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;quot;devDependencies&amp;quot;: {&lt;br /&gt;
    &amp;quot;jshint&amp;quot;: &amp;quot;^2.6.0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;scripts&amp;quot;: {&lt;br /&gt;
    &amp;quot;test&amp;quot;: &amp;quot;./node_modules/jshint/bin/jshint index.js&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
et incrémentez le numéro de version.&lt;br /&gt;
&lt;br /&gt;
Faites un &amp;#039;&amp;#039;&amp;#039;Commit&amp;#039;&amp;#039;&amp;#039; puis un &amp;#039;&amp;#039;&amp;#039;Push&amp;#039;&amp;#039;&amp;#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Remarque:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;jshint&amp;#039;&amp;#039;&amp;#039; peut être lancé localement avec les commandes suivantes:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo npm install jshint&lt;br /&gt;
jshint index.js&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A lire&lt;br /&gt;
* http://docs.travis-ci.com/user/languages/javascript-with-nodejs/&lt;br /&gt;
* https://github.com/docdis/learn-travis/blob/master/README.md&lt;br /&gt;
&lt;br /&gt;
=Séance 2b: Livraison en continue=&lt;br /&gt;
&lt;br /&gt;
==[[Heroku]]==&lt;br /&gt;
[https://www.heroku.com/ Heroku] est une plateforme cloud de type PaaS permettant l&amp;#039;exécution d&amp;#039;applications et de services en ligne écrits dans les langages et plateformes suivantes : Ruby, [[Node.js]], [[Python]], Java, et PHP.&lt;br /&gt;
&lt;br /&gt;
# Créez un compte gratuit sur [https://signup.heroku.com Heroku]&lt;br /&gt;
# Forkez le dépôt https://github.com/heroku/node-js-getting-started&lt;br /&gt;
# Dans Heroku, créez une nouvelle app Node.js, et liez-la au repository Github créé à l&amp;#039;étape précédente&lt;br /&gt;
# Choisissez l&amp;#039;option &amp;quot;Déploiement automatique&amp;quot; depuis la branche **master**&lt;br /&gt;
# Modifiez le fichier index.js pour afficher la version de service dans la page HTML&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 var fs = require(&amp;#039;fs&amp;#039;);&lt;br /&gt;
 var package = JSON.parse(fs.readFileSync(&amp;#039;./package.json&amp;#039;, &amp;#039;utf8&amp;#039;));&lt;br /&gt;
 var version=package.version;&lt;br /&gt;
...&lt;br /&gt;
 response.send(&amp;#039;Hello World! (current version: &amp;#039;+version+&amp;#039;)&amp;#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incrémentez le numéro de version dans le fichier &amp;#039;&amp;#039;package.json&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Faites un &amp;#039;&amp;#039;&amp;#039;Commit&amp;#039;&amp;#039;&amp;#039; puis un &amp;#039;&amp;#039;&amp;#039;Push&amp;#039;&amp;#039;&amp;#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
Naviguez l&amp;#039;application sur Heroku&lt;br /&gt;
&lt;br /&gt;
# Modifiez le fichier index.js pour franciser le message dans la page HTML&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
 response.send(&amp;#039;Bonjour Tout Le Monde! (version courante: &amp;#039;+version+&amp;#039;)&amp;#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incrémentez le numéro de version dans le fichier &amp;#039;&amp;#039;&amp;#039;package.json&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Faites un &amp;#039;&amp;#039;&amp;#039;Commit&amp;#039;&amp;#039;&amp;#039; puis un &amp;#039;&amp;#039;&amp;#039;Push&amp;#039;&amp;#039;&amp;#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
Naviguez l&amp;#039;application sur Heroku&lt;br /&gt;
&lt;br /&gt;
=Séance 3: Builders=&lt;br /&gt;
Les builders permettent d&amp;#039;automatiser l&amp;#039;exécution en chaine des outils pour la production et la livraison en production des produits logiciels.&lt;br /&gt;
&lt;br /&gt;
==[[Make]]==&lt;br /&gt;
&lt;br /&gt;
==[[Ant]]==&lt;br /&gt;
&lt;br /&gt;
Faire les exercices 0, 1, 3 de ./tpant.htm dans http://lig-membres.imag.fr/donsez/cours/tpant.zip&lt;br /&gt;
&lt;br /&gt;
==[[Maven]]==&lt;br /&gt;
&lt;br /&gt;
[http://maven.apache.org/download.cgi Charger et installer Maven 3].&lt;br /&gt;
&lt;br /&gt;
Debian/Ubuntu &amp;amp; friends:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install maven&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mvn -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Faites une copie du projet, basée sur Maven:&lt;br /&gt;
&lt;br /&gt;
# Dans votre dépôt Git, créez un dossier &amp;#039;&amp;#039;&amp;#039;cron4j-mvn&amp;#039;&amp;#039;&amp;#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&amp;#039;[https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype] Maven [http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-quickstart/ maven-archetype-quickstart] (la version des sources de cron4j utilisés est la 2.5.5) (groupId: it.sauronsoftware.cron4j, artifactId: cron4j):&lt;br /&gt;
#:&amp;lt;pre&amp;gt;mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Cette commande crée un projet avec un fichier &amp;#039;&amp;#039;pom.xml&amp;#039;&amp;#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &amp;#039;&amp;#039;&amp;#039;cron4j-original&amp;#039;&amp;#039;&amp;#039; ([https://github.com/donsez/tagl https://github.com/donsez/tagl]) dans le dossier &amp;#039;&amp;#039;&amp;#039;src/main/java&amp;#039;&amp;#039;&amp;#039; de votre projet Maven&lt;br /&gt;
# Faites un essai de compilation:&lt;br /&gt;
#:&amp;lt;pre&amp;gt;mvn clean verify&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Lancez un des exemples avec mvn exec:java -Dexec.mainClass=&amp;quot;com.example.Main&amp;quot; [-Dexec.args=&amp;quot;argument1&amp;quot;] ... ([http://mojo.codehaus.org/exec-maven-plugin/usage.html doc. exec plugin], [http://mojo.codehaus.org/exec-maven-plugin/java-mojo.html doc. Exec:java goal])&lt;br /&gt;
# Enfin modifiez le fichier &amp;#039;&amp;#039;&amp;#039;.travis.yml&amp;#039;&amp;#039;&amp;#039; à la racine de votre dépôt Git afin que Travis exécute la commande &amp;#039;&amp;#039;&amp;#039;mvn clean verify&amp;#039;&amp;#039;&amp;#039; à chaque mise à jour du dépôt GitHub.&lt;br /&gt;
&lt;br /&gt;
==Tests Unitaires avec JUnit 4==&lt;br /&gt;
Survoller le tutoriel [http://www.vogella.com/tutorials/JUnit/article.html Unit Testing with JUnit]&lt;br /&gt;
&lt;br /&gt;
# Veillez à bien utiliser la dépendance JUnit 4.8.2 dans pom.xml&lt;br /&gt;
# Ajouter le test unitaire suivant au projet, dans le fichier &amp;#039;&amp;#039;&amp;#039;src/test/it/sauronsoftware/SchedulingPatternTest.java&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
package it.sauronsoftware;&lt;br /&gt;
&lt;br /&gt;
import it.sauronsoftware.cron4j.SchedulingPattern;&lt;br /&gt;
import it.sauronsoftware.cron4j.InvalidPatternException;&lt;br /&gt;
&lt;br /&gt;
import static org.junit.Assert.assertEquals;&lt;br /&gt;
import static org.junit.Assert.assertTrue;&lt;br /&gt;
&lt;br /&gt;
import org.junit.AfterClass;&lt;br /&gt;
import org.junit.BeforeClass;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
&lt;br /&gt;
public class SchedulingPatternTest {&lt;br /&gt;
&lt;br /&gt;
  @BeforeClass&lt;br /&gt;
  public static void testSetup() {&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  @AfterClass&lt;br /&gt;
  public static void testCleanup() {&lt;br /&gt;
    // Teardown for data used by the unit tests&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  @Test(expected = InvalidPatternException.class)&lt;br /&gt;
  public void testExceptionIsThrown() {&lt;br /&gt;
    SchedulingPattern sp = new SchedulingPattern(&amp;quot;0 5 * *&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  @Test&lt;br /&gt;
  public void testPattern() {&lt;br /&gt;
    String pattern;&lt;br /&gt;
    pattern=&amp;quot;0 5 * * *|8 10 * * *|22 17 * * *&amp;quot;;&lt;br /&gt;
    assertTrue(pattern + &amp;quot;is correct&amp;quot;, SchedulingPattern.validate(pattern));&lt;br /&gt;
    pattern=&amp;quot;0 5 * *&amp;quot;;&lt;br /&gt;
    assertTrue(pattern + &amp;quot;is correct&amp;quot;, SchedulingPattern.validate(pattern));&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Committez et Pushez ce nouveau fichier, pour que Travis lance les tests dès que possible&lt;br /&gt;
# Lancez les tests unitaires avec &amp;lt;pre&amp;gt;mvn test&amp;lt;/pre&amp;gt; Ce test va &amp;#039;&amp;#039;&amp;#039;échouer&amp;#039;&amp;#039;&amp;#039;: corrigez le.&lt;br /&gt;
# Committez et Pushez la version corrigée des tests: Travis enverra un mail pour indiquer si les tests échouent ou non&lt;br /&gt;
#: &amp;#039;&amp;#039;&amp;#039;Attention:&amp;#039;&amp;#039;&amp;#039; Travis va exécuter les tests &amp;#039;&amp;#039;dès que possible&amp;#039;&amp;#039;. Il est possible de recevoir un mail indiquant que les tests du premier &amp;#039;&amp;#039;push&amp;#039;&amp;#039; échouent alors que l&amp;#039;on a déjà &amp;#039;&amp;#039;pushé&amp;#039;&amp;#039; la correction.&lt;br /&gt;
# Naviguez sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
# Créez des tests unitaires supplémentaire du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===[[Maven]] avec [[Travis-CI]]===&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &amp;#039;&amp;#039;&amp;#039;tagl&amp;#039;&amp;#039;&amp;#039; d&amp;#039;un autre binome (i.e. autre que &amp;#039;&amp;#039;donsez/tagl&amp;#039;&amp;#039;)&lt;br /&gt;
#: &amp;#039;&amp;#039;&amp;#039;Attention:&amp;#039;&amp;#039;&amp;#039; donnez lui un nom différent (e.g. &amp;#039;&amp;#039;tagl-licensing&amp;#039;&amp;#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&amp;#039;état du projet (bonne pratique)&lt;br /&gt;
#:&amp;lt;pre&amp;gt;mvn clean verify&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Situez vous dans une nouvelle branch git:&lt;br /&gt;
#:&amp;lt;pre&amp;gt;git checkout -b add-license&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Ajoutez une bannière de licence dans le fichier &amp;#039;&amp;#039;&amp;#039;cron4j-mvn/pom.xml&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# Lancez une nouvelle compilation pour valider vos modifications&lt;br /&gt;
# Commitez et pushez (vers votre fork de ce dépôt, i.e. &amp;#039;&amp;#039;tagl-licensing&amp;#039;&amp;#039;) (pour pusher une branche nouvellement créée: git push origin add-license)&lt;br /&gt;
# Via le site de GitHub, proposez un &amp;quot;Pull Request&amp;quot; au projet initial&lt;br /&gt;
&lt;br /&gt;
Vous pouvez ensuite supprimer le clone de ce fork.&lt;br /&gt;
Lorsque le &amp;#039;&amp;#039;pull request&amp;#039;&amp;#039; aura été accepté, vous pourrez supprimer votre fork (&amp;#039;&amp;#039;tagl-licensing&amp;#039;&amp;#039;) de votre compte GitHub.&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt &amp;#039;&amp;#039;tagl&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
# Ajoutez le plugin [http://mojo.codehaus.org/cobertura-maven-plugin/usage.html Cobertura] à votre projet Maven.&lt;br /&gt;
## Configurez le plugin pour [http://mojo.codehaus.org/cobertura-maven-plugin/examples/report-formats.html générer un rapport] HTML. Le résultat se trouvera dans &amp;#039;&amp;#039;target/site/cobertura&amp;#039;&amp;#039;&lt;br /&gt;
## Le plugin ne s&amp;#039;exécute automatiquement pas durant la compilation, il faut utiliser la commande : &amp;lt;pre&amp;gt;mvn cobertura:cobertura&amp;lt;/pre&amp;gt;&lt;br /&gt;
## &amp;#039;&amp;#039;&amp;#039;Bonus:&amp;#039;&amp;#039;&amp;#039; Modifiez le fichier &amp;#039;&amp;#039;pom.xml&amp;#039;&amp;#039; pour que le &amp;#039;&amp;#039;goal&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;cobertura&amp;#039;&amp;#039;&amp;#039; soit exécuté pendant la &amp;#039;&amp;#039;phase&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;package&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# Répondez aux questions : &amp;#039;&amp;#039;Mais qu&amp;#039;est ce que la couverture de code ? En quoi c&amp;#039;est utile ?&amp;#039;&amp;#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&amp;#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&amp;#039;autres.&lt;br /&gt;
# Regardez les exemples d&amp;#039;utilisation de cron4j dans cron4j-original/examples&lt;br /&gt;
# À rendre : pom.xml&lt;br /&gt;
&lt;br /&gt;
===Bonus Track===&lt;br /&gt;
&lt;br /&gt;
====Clone SVN -&amp;gt; Git====&lt;br /&gt;
&lt;br /&gt;
Source: http://www.yterium.net/Migrer-un-projet-SVN-vers-GIT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Cloner le dépôt SVN en dépôt Git (conservation historique)&lt;br /&gt;
$ git svn clone  svn://svn.code.sf.net/p/cron4j/code/trunk cron4j-original&lt;br /&gt;
$ cd cron4j-original&lt;br /&gt;
# Test compilation&lt;br /&gt;
$ ant jar&lt;br /&gt;
$ cd ..&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Préparation TAGL====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Clone du dépôt TAGL&lt;br /&gt;
$ git clone git@github.com:donsez/tagl.git&lt;br /&gt;
$ cd tagl&lt;br /&gt;
# &amp;quot;Fetch&amp;quot; du dépôt local cloné précédemment&lt;br /&gt;
$ git fetch file://$(pwd)/../cron4j-original&lt;br /&gt;
# Fusion de ce qui vient d&amp;#039;être fetché&lt;br /&gt;
$ git merge FETCH_HEAD&lt;br /&gt;
# Envoi sur le serveur&lt;br /&gt;
$ git push&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Cherry-picking: reprise des modifications d&amp;#039;un collègue====&lt;br /&gt;
&lt;br /&gt;
On considère que:&lt;br /&gt;
&lt;br /&gt;
* votre dépôt Git distant est à l&amp;#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&amp;#039;adresse URL_COLLEGUE&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Dossier temporaire&lt;br /&gt;
cd /tmp&lt;br /&gt;
&lt;br /&gt;
# Clone de votre dépôt&lt;br /&gt;
git clone URL_DEPOT mon_depot&lt;br /&gt;
&lt;br /&gt;
# Déplacement dans votre dépôt&lt;br /&gt;
cd mon_depot&lt;br /&gt;
&lt;br /&gt;
# Définition du dépôt distant&lt;br /&gt;
git remote add collegue URL_COLLEGUE&lt;br /&gt;
&lt;br /&gt;
# Récupération des infos du dépôt du collègue&lt;br /&gt;
git fetch collegue&lt;br /&gt;
&lt;br /&gt;
# Maintenant, on peut voir les branches du collègue&lt;br /&gt;
git branch -a&lt;br /&gt;
&lt;br /&gt;
# On peut fusionner avec une branche&lt;br /&gt;
git merge collegue/master&lt;br /&gt;
&lt;br /&gt;
# Si vous avez des conflits, éditez les fichiers concernés,&lt;br /&gt;
# et committez avec git commit&lt;br /&gt;
&lt;br /&gt;
# Push vers votre dépôt distant&lt;br /&gt;
git push origin&lt;br /&gt;
&lt;br /&gt;
# Optionnel: supprimez la référence vers le dépôt du collègue&lt;br /&gt;
git remote rm collegue&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Archetype webapp====&lt;br /&gt;
L&amp;#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&amp;#039;une webapp. Créez un simple webapp monsite en version 0.1.0. (add/commit/push). Vous pourrez tester cette webapp en ajoutant au pom.xml le [https://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin plugin maven Jetty].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mvn -Djetty.port=9999 jetty:run&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Naviguez sur http://localhost:9999/monsite&lt;br /&gt;
&lt;br /&gt;
====Scrum tools====&lt;br /&gt;
Ces 3 services peuvent être couplé à votre dépôt GitHub pour votre gestion de projet agile avec [[Scrum]] :&lt;br /&gt;
* http://www.acunote.com/&lt;br /&gt;
* http://backlogtool.com/&lt;br /&gt;
* http://www.scrumdo.com/&lt;br /&gt;
&lt;br /&gt;
L&amp;#039;activation se fait via &amp;#039;&amp;#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=Séance 4: AOP &amp;amp; AspectJ=&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;(abandonnée en 2014-2015)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &amp;#039;&amp;#039;cron4j-mvn&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
# Ajoutez le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
# Ajoutez un aspect de trace à l&amp;#039;invocation des méthodes &amp;#039;&amp;#039;&amp;#039;run()&amp;#039;&amp;#039;&amp;#039; de l&amp;#039;interface java.lang.Runnable (uniquement pour les objets &amp;#039;&amp;#039;schedulé&amp;#039;&amp;#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&amp;#039;exécution de la tâche&lt;br /&gt;
# Préparez un nouveau test (nouvelle classe) démarrant un Scheduler Cron4j et validant l&amp;#039;exécution d&amp;#039;une tâche au bout d&amp;#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&amp;#039;exécution de &amp;#039;&amp;#039;&amp;#039;mvn test&amp;#039;&amp;#039;&amp;#039;, vous devez voir apparaître les traces préparées dans votre aspect.&lt;br /&gt;
&lt;br /&gt;
Liens utiles:&lt;br /&gt;
* [http://ridgetopsolutions.com/blog/2013/02/12/getting-started-with-aspectj-and-maven/ Getting started with AspectJ and Maven]&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
&lt;br /&gt;
# Complétez l&amp;#039;aspect de trace avec le positionnement du [http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html java.lang.ThreadLocal] pour passer 1) l&amp;#039;identifiant du job et 2) le compteur des appels de la méthode de l&amp;#039;objet.&lt;br /&gt;
&lt;br /&gt;
=Séance 4 : Gestion d&amp;#039;un dépôt d&amp;#039;artefacts=&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;(introduite en 2015-2016)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Le dépôt https://www.npmjs.com/ est le dépôt principal des artefacts pour Javascript et [[Node.js]]. [https://docs.npmjs.com/getting-started/what-is-npm Pour en savoir plus ...]&lt;br /&gt;
&lt;br /&gt;
Côté client, il s&amp;#039;utilise avec les commandes npm, [https://www.npmjs.com/package/bower bower], ...&lt;br /&gt;
&lt;br /&gt;
Ce TP a pour objectif de faire évoluer l&amp;#039;artefact suivant XXXX et l&amp;#039;ajouter au dépôt npmjs (manuellement et via Travis-CI).&lt;br /&gt;
&lt;br /&gt;
Il vous faut pour cela comprendre le format du manifeste [https://docs.npmjs.com/files/package.json package.json]&lt;br /&gt;
&lt;br /&gt;
=Séance 5: Pelix &amp;amp; iPOPO=&lt;br /&gt;
&lt;br /&gt;
Pelix est une plate-forme d&amp;#039;application à services (SOA).&lt;br /&gt;
iPOPO est un modèle de composants orientés services (SOCM).&lt;br /&gt;
&lt;br /&gt;
La documentation de Pelix et iPOPO est disponible sur https://ipopo.coderxpress.net/&lt;br /&gt;
&lt;br /&gt;
===Installation de iPOPO===&lt;br /&gt;
&lt;br /&gt;
* Pour installer iPOPO, lancer la commande :&lt;br /&gt;
&lt;br /&gt;
   pip install --user iPOPO&lt;br /&gt;
&lt;br /&gt;
* ou par les sources:&lt;br /&gt;
** Cloner le dépôt Git depuis https://github.com/tcalmant/ipopo&lt;br /&gt;
** Se placer dans la branche &amp;#039;&amp;#039;dev&amp;#039;&amp;#039;&lt;br /&gt;
** Lancer la commande:&lt;br /&gt;
&lt;br /&gt;
   sudo python setup.py install&lt;br /&gt;
&lt;br /&gt;
===Shell Pelix===&lt;br /&gt;
&lt;br /&gt;
Pour lancer un shell Pelix, utilisez la commande:&lt;br /&gt;
&lt;br /&gt;
   python -m pelix.shell.console&lt;br /&gt;
&lt;br /&gt;
Les commandes disponibles sont décrites ici: [https://ipopo.coderxpress.net/wiki/doku.php?id=ipopo:refcards:shell Shell Commands]&lt;br /&gt;
&lt;br /&gt;
===Rappels de Python===&lt;br /&gt;
&lt;br /&gt;
* Pas de déclaration du type d&amp;#039;une variable&lt;br /&gt;
* Les méthodes d&amp;#039;une classe ont toute comme premier paramètre &amp;#039;&amp;#039;self&amp;#039;&amp;#039;, équivalent du &amp;#039;&amp;#039;this&amp;#039;&amp;#039; en Java.&lt;br /&gt;
* Blocs définis par indentation (4 espaces ou 1 tab)&lt;br /&gt;
* Une ligne finissant par &amp;#039;:&amp;#039; démarre toujours un bloc&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
# -- Content-Encoding: UTF-8 --&lt;br /&gt;
# Import d&amp;#039;un module&lt;br /&gt;
import pelix&lt;br /&gt;
&lt;br /&gt;
# Définition d&amp;#039;une classe&lt;br /&gt;
class MaClasse:&lt;br /&gt;
   # Constructeur&lt;br /&gt;
   def __init__(self):&lt;br /&gt;
       self.default = &amp;quot;stanger&amp;quot;&lt;br /&gt;
       print(&amp;quot;Classe construite&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   # Méthode, avec un argument&lt;br /&gt;
   def sayHello(self, name):&lt;br /&gt;
       if not name:&lt;br /&gt;
           # Nom vide ou nul&lt;br /&gt;
           return &amp;quot;Hello, &amp;quot; + str(self.default)&lt;br /&gt;
       else:&lt;br /&gt;
           # Nom valide&lt;br /&gt;
           return &amp;quot;Hello, &amp;quot; + str(name)&lt;br /&gt;
&lt;br /&gt;
objet = MaClasse()&lt;br /&gt;
print(objet.sayHello(&amp;quot;&amp;quot;))&lt;br /&gt;
print(objet.sayHello(&amp;quot;World&amp;quot;))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Service Ping-Pong===&lt;br /&gt;
&lt;br /&gt;
1. Écrire un fichier &amp;#039;&amp;#039;pong.py&amp;#039;&amp;#039;, définissant une classe &amp;#039;&amp;#039;Pong&amp;#039;&amp;#039; ayant une méthode &amp;#039;&amp;#039;pong&amp;#039;&amp;#039; prenant en paramètre un message et retournant le message préfixé par &amp;quot;PONG:&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Exemple: &lt;br /&gt;
   &lt;br /&gt;
      pong = Pong()&lt;br /&gt;
      pong.pong(&amp;quot;Hello&amp;quot;) # &amp;lt;-- Retourne &amp;quot;PONG:Hello&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. Écrire un fichier &amp;#039;&amp;#039;ping.py&amp;#039;&amp;#039;, définissant une classe &amp;#039;&amp;#039;Ping&amp;#039;&amp;#039; ayant une méthode &amp;#039;&amp;#039;ping&amp;#039;&amp;#039; prenant en paramètre un message, créant un objet Pong et retournant le résultat de Pong.pong(message) préfixé par &amp;quot;PING:&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Exemple:&lt;br /&gt;
&lt;br /&gt;
      ping = Ping()&lt;br /&gt;
      ping.ping(&amp;quot;Hello&amp;quot;) # &amp;lt;-- Retourne &amp;quot;PING:PONG:Hello&amp;quot;&lt;br /&gt;
&lt;br /&gt;
3. Transformer le fichier &amp;#039;&amp;#039;pong.py&amp;#039;&amp;#039; pour qu&amp;#039;il devienne un bundle Pelix enregistrant un objet Pong comme étant un service ayant pour spécification &amp;quot;tagl.pong&amp;quot;&lt;br /&gt;
* Définir une classe &amp;#039;&amp;#039;Activator&amp;#039;&amp;#039;, décorée avec &amp;#039;&amp;#039;@BundleActivator&amp;#039;&amp;#039;&lt;br /&gt;
* Enregistrer le service dans la méthode &amp;#039;&amp;#039;Activator.start&amp;#039;&amp;#039; et le désenregistrer dans &amp;#039;&amp;#039;Activator.stop&amp;#039;&amp;#039;&lt;br /&gt;
* S&amp;#039;inspirer du fichier &amp;quot;ipopo/samples/remote/provider.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dans un shell Pelix, installer et démarrer le bundle &amp;#039;pong&amp;#039; et vérifier que le service est bien inscrit avec la commande &amp;#039;&amp;#039;sl&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
4.Transformer la classe &amp;#039;&amp;#039;Ping&amp;#039;&amp;#039; dans &amp;#039;&amp;#039;ping.py&amp;#039;&amp;#039; en un composant iPOPO&lt;br /&gt;
* L&amp;#039;objet Pong utilisé dans &amp;#039;&amp;#039;ping()&amp;#039;&amp;#039; doit être un service injecté par iPOPO (&amp;#039;&amp;#039;@Requires&amp;#039;&amp;#039;)&lt;br /&gt;
* Appeler la méthode &amp;#039;&amp;#039;ping()&amp;#039;&amp;#039; dès que le service Pong est injecté (&amp;#039;&amp;#039;@BindField&amp;#039;&amp;#039;) ou disparait (&amp;#039;&amp;#039;@UnbindField&amp;#039;&amp;#039;)&lt;br /&gt;
* S&amp;#039;inspirer du fichier &amp;quot;ipopo/samples/remote/consumer.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Dans un shell Pelix, installer et démarrer le bundle &amp;#039;ping&amp;#039; et vérifier son comportement si le bundle &amp;#039;&amp;#039;pong&amp;#039;&amp;#039; ou le bundle &amp;#039;&amp;#039;ping&amp;#039;&amp;#039; est arrêté et redémarré.&lt;br /&gt;
&lt;br /&gt;
5. Mettre à jour le bundle &amp;#039;&amp;#039;pong&amp;#039;&amp;#039;&lt;br /&gt;
* Remplacer le préfixe &amp;quot;PONG&amp;quot; par &amp;quot;NI&amp;quot;&lt;br /&gt;
* Dans le shell Pelix, mettre à jour le bundle &amp;#039;&amp;#039;pong&amp;#039;&amp;#039; sans redémarrer la plate-forme (commande &amp;#039;&amp;#039;udpate&amp;#039;&amp;#039;).&lt;br /&gt;
* Vérifier les traces dans le shell pour valider la mise à jour du service.&lt;br /&gt;
&lt;br /&gt;
===Remote Services===&lt;br /&gt;
&lt;br /&gt;
* Ajouter les propriétés permettant l&amp;#039;export du service Pong dans &amp;#039;&amp;#039;pong.py&amp;#039;&amp;#039; (s&amp;#039;inspirer de &amp;#039;&amp;#039;provider.py&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
* Lancer deux shells iPOPO (dans deux terminaux)&lt;br /&gt;
* Dans chaque shell iPOPO, installer les bundles:&lt;br /&gt;
** &amp;#039;&amp;#039;pelix.remote.dispatcher&amp;#039;&amp;#039;: Exportateur de services&lt;br /&gt;
** &amp;#039;&amp;#039;pelix.remote.registry&amp;#039;&amp;#039;; Importateur de services&lt;br /&gt;
** &amp;#039;&amp;#039;pelix.remote.discovery.multicast&amp;#039;&amp;#039;: Découverte de services via Multicast&lt;br /&gt;
** &amp;#039;&amp;#039;pelix.remote.xml_rpc&amp;#039;&amp;#039;: Transport XML-RPC&lt;br /&gt;
** &amp;#039;&amp;#039;pelix.http.basic&amp;#039;&amp;#039;: Serveur HTTP&lt;br /&gt;
&lt;br /&gt;
Attention: il peut être nécessaire de désactiver votre pare-feu pour que les Remote Services fonctionnent&lt;br /&gt;
&lt;br /&gt;
* Instancier les composants depuis le shell iPOPO, dans chaque framework:&lt;br /&gt;
** Serveur HTTP sur le port 8080: &amp;#039;&amp;#039;instantiate pelix.http.service.basic.factory http-server pelix.http.port=8080&amp;#039;&amp;#039; (penser à changer de port dans chaque framework)&lt;br /&gt;
** Multicast Discovery: &amp;#039;&amp;#039;instantiate pelix-remote-discovery-multicast-factory multicast-discovery&amp;#039;&amp;#039;&lt;br /&gt;
** XML-RPC Exporter: &amp;#039;&amp;#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-exporter&amp;#039;&amp;#039;&lt;br /&gt;
** XML-RPC Importer: &amp;#039;&amp;#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-importer&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* Installer le bundle &amp;#039;&amp;#039;ping&amp;#039;&amp;#039; dans un des frameworks et le bundle &amp;#039;&amp;#039;pong&amp;#039;&amp;#039; dans l&amp;#039;autre.&lt;br /&gt;
* Le composant ping peut appeler le service pong, qui est dans l&amp;#039;autre framework.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Voir le code de &amp;#039;&amp;#039;run_remote.py&amp;#039;&amp;#039; pour voir comment démarrer un framework Pelix et installer des bundles depuis Python.&lt;br /&gt;
* Jouer un peu avec &amp;#039;&amp;#039;run_remote.py&amp;#039;&amp;#039; (voir &amp;#039;&amp;#039;run_remote.py --help&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
=Séance 6=&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
=Séance 7=&lt;br /&gt;
Faire un projet PDE pour un bundle cron4j.gogo (indépendant de cron4j.bundle)&lt;br /&gt;
&lt;br /&gt;
Utilisation de https://eclipse.org/tycho/&lt;/div&gt;</summary>
		<author><name>Donsez</name></author>
	</entry>
</feed>