<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://air.imag.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Calmant</id>
	<title>air - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://air.imag.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Calmant"/>
	<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php/Special:Contributions/Calmant"/>
	<updated>2026-06-01T01:52:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://air.imag.fr/index.php?title=Services_%C3%A9tendus_pour_le_mod%C3%A8le_de_composants_iPOPO_pour_Python&amp;diff=25597</id>
		<title>Services étendus pour le modèle de composants iPOPO pour Python</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Services_%C3%A9tendus_pour_le_mod%C3%A8le_de_composants_iPOPO_pour_Python&amp;diff=25597"/>
		<updated>2016-01-05T10:21:59Z</updated>

		<summary type="html">&lt;p&gt;Calmant: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tuteurs :  Didier Donsez &amp;amp; Thomas Calmant&lt;br /&gt;
&lt;br /&gt;
Étudiants: 2 RICM4&lt;br /&gt;
&lt;br /&gt;
L&#039;objectif de ce projet est de développer une suite de services utilitaires pour la plateforme open-source [[iPOPO]].&lt;br /&gt;
&lt;br /&gt;
=Contexte=&lt;br /&gt;
&lt;br /&gt;
[[iPOPO]] est un modèle de composants logiciels pour le langage Python. iPOPO s&#039;inspire des principes de la spécification [[OSGi]] pour Java. Les composants iPOPO peuvent être ajoutés, retirés et mis à jour dynamiquement (i.e. sans redémarrer le programme Python).&lt;br /&gt;
&lt;br /&gt;
=Cahier des charges=&lt;br /&gt;
&lt;br /&gt;
iPOPO implémente quelques services définis dans la spécification OSGi:&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/cm/ConfigurationAdmin.html Configuration Admin]&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/event/EventAdmin.html Event Admin]&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/http/HttpService.html HTTP Service]&lt;br /&gt;
&lt;br /&gt;
D&#039;autres services pourraient être implémentés, tels que:&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/wireadmin/package-summary.html Wire Admin]&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/log/LogService.html Log Service]&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/prefs/Preferences.html Preferences Service]&lt;br /&gt;
* [https://osgi.org/javadoc/r4v42/org/osgi/service/useradmin/UserAdmin.html User Admin]&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
Il serait également possible de travailler sur le shell iPOPO:&lt;br /&gt;
* en ajoutant la notion d&#039;utilisateurs et de droit d&#039;exécution des commandes&lt;br /&gt;
* en chiffrant la liaison distante au shell&lt;br /&gt;
* en ajoutant la notion de pipe pour utiliser le résultat d&#039;une commande comme entrée d&#039;une seconde.&lt;br /&gt;
&lt;br /&gt;
=Liens=&lt;br /&gt;
* [https://ipopo.coderxpress.net/ iPOPO]&lt;br /&gt;
* [https://www.osgi.org/developer/specifications/ Spécification OSGi]&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=22583</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=22583"/>
		<updated>2015-03-27T07:40:28Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Rappels de Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
Anciennes versions : [[TAGL/TP 2014]]&lt;br /&gt;
&lt;br /&gt;
=Séance 1 : Gestion de versions=&lt;br /&gt;
==Git==&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#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;
# &#039;&#039;Fork&#039;&#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 &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
[[Travis-CI]] utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;package.json&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque:&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;jshint&#039;&#039;&#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&#039;exécution d&#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&#039;étape précédente&lt;br /&gt;
# Choisissez l&#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(&#039;fs&#039;);&lt;br /&gt;
 var package = JSON.parse(fs.readFileSync(&#039;./package.json&#039;, &#039;utf8&#039;));&lt;br /&gt;
 var version=package.version;&lt;br /&gt;
...&lt;br /&gt;
 response.send(&#039;Hello World! (current version: &#039;+version+&#039;)&#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 &#039;&#039;package.json&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Faites un &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
Naviguez l&#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(&#039;Bonjour Tout Le Monde! (version courante: &#039;+version+&#039;)&#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 &#039;&#039;&#039;package.json&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Faites un &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
Naviguez l&#039;application sur Heroku&lt;br /&gt;
&lt;br /&gt;
=Séance 3: Builders=&lt;br /&gt;
Les builders permettent d&#039;automatiser l&#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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; ([https://github.com/donsez/tagl https://github.com/donsez/tagl]) dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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 &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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 &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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 &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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 &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Séance 4: AOP &amp;amp; AspectJ=&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&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&#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 &#039;&#039;dev&#039;&#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&#039;une variable&lt;br /&gt;
* Les méthodes d&#039;une classe ont toute comme premier paramètre &#039;&#039;self&#039;&#039;, équivalent du &#039;&#039;this&#039;&#039; en Java.&lt;br /&gt;
* Blocs définis par indentation (4 espaces ou 1 tab)&lt;br /&gt;
* Une ligne finissant par &#039;:&#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&#039;un module&lt;br /&gt;
import pelix&lt;br /&gt;
&lt;br /&gt;
# Définition d&#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 &#039;&#039;pong.py&#039;&#039;, définissant une classe &#039;&#039;Pong&#039;&#039; ayant une méthode &#039;&#039;pong&#039;&#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 &#039;&#039;ping.py&#039;&#039;, définissant une classe &#039;&#039;Ping&#039;&#039; ayant une méthode &#039;&#039;ping&#039;&#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 &#039;&#039;pong.py&#039;&#039; pour qu&#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 &#039;&#039;Activator&#039;&#039;, décorée avec &#039;&#039;@BundleActivator&#039;&#039;&lt;br /&gt;
* Enregistrer le service dans la méthode &#039;&#039;Activator.start&#039;&#039; et le désenregistrer dans &#039;&#039;Activator.stop&#039;&#039;&lt;br /&gt;
* S&#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 &#039;pong&#039; et vérifier que le service est bien inscrit avec la commande &#039;&#039;sl&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
4.Transformer la classe &#039;&#039;Ping&#039;&#039; dans &#039;&#039;ping.py&#039;&#039; en un composant iPOPO&lt;br /&gt;
* L&#039;objet Pong utilisé dans &#039;&#039;ping()&#039;&#039; doit être un service injecté par iPOPO (&#039;&#039;@Requires&#039;&#039;)&lt;br /&gt;
* Appeler la méthode &#039;&#039;ping()&#039;&#039; dès que le service Pong est injecté (&#039;&#039;@BindField&#039;&#039;) ou disparait (&#039;&#039;@UnbindField&#039;&#039;)&lt;br /&gt;
* S&#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 &#039;ping&#039; et vérifier son comportement si le bundle &#039;&#039;pong&#039;&#039; ou le bundle &#039;&#039;ping&#039;&#039; est arrêté et redémarré.&lt;br /&gt;
&lt;br /&gt;
5. Mettre à jour le bundle &#039;&#039;pong&#039;&#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 &#039;&#039;pong&#039;&#039; sans redémarrer la plate-forme (commande &#039;&#039;udpate&#039;&#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&#039;export du service Pong dans &#039;&#039;pong.py&#039;&#039; (s&#039;inspirer de &#039;&#039;provider.py&#039;&#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;
** &#039;&#039;pelix.remote.dispatcher&#039;&#039;: Exportateur de services&lt;br /&gt;
** &#039;&#039;pelix.remote.registry&#039;&#039;; Importateur de services&lt;br /&gt;
** &#039;&#039;pelix.remote.discovery.multicast&#039;&#039;: Découverte de services via Multicast&lt;br /&gt;
** &#039;&#039;pelix.remote.xml_rpc&#039;&#039;: Transport XML-RPC&lt;br /&gt;
** &#039;&#039;pelix.http.basic&#039;&#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: &#039;&#039;instantiate pelix.http.service.basic.factory http-server pelix.http.port=8080&#039;&#039; (penser à changer de port dans chaque framework)&lt;br /&gt;
** Multicast Discovery: &#039;&#039;instantiate pelix-remote-discovery-multicast-factory multicast-discovery&#039;&#039;&lt;br /&gt;
** XML-RPC Exporter: &#039;&#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-exporter&#039;&#039;&lt;br /&gt;
** XML-RPC Importer: &#039;&#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-importer&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Installer le bundle &#039;&#039;ping&#039;&#039; dans un des frameworks et le bundle &#039;&#039;pong&#039;&#039; dans l&#039;autre.&lt;br /&gt;
* Le composant ping peut appeler le service pong, qui est dans l&#039;autre framework.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Voir le code de &#039;&#039;run_remote.py&#039;&#039; pour voir comment démarrer un framework Pelix et installer des bundles depuis Python.&lt;br /&gt;
* Jouer un peu avec &#039;&#039;run_remote.py&#039;&#039; (voir &#039;&#039;run_remote.py --help&#039;&#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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=22582</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=22582"/>
		<updated>2015-03-27T07:22:28Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 5: Pelix &amp;amp; iPOPO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
Anciennes versions : [[TAGL/TP 2014]]&lt;br /&gt;
&lt;br /&gt;
=Séance 1 : Gestion de versions=&lt;br /&gt;
==Git==&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#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;
# &#039;&#039;Fork&#039;&#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 &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
[[Travis-CI]] utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;package.json&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Remarque:&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;jshint&#039;&#039;&#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&#039;exécution d&#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&#039;étape précédente&lt;br /&gt;
# Choisissez l&#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(&#039;fs&#039;);&lt;br /&gt;
 var package = JSON.parse(fs.readFileSync(&#039;./package.json&#039;, &#039;utf8&#039;));&lt;br /&gt;
 var version=package.version;&lt;br /&gt;
...&lt;br /&gt;
 response.send(&#039;Hello World! (current version: &#039;+version+&#039;)&#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 &#039;&#039;package.json&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Faites un &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
Naviguez l&#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(&#039;Bonjour Tout Le Monde! (version courante: &#039;+version+&#039;)&#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 &#039;&#039;&#039;package.json&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Faites un &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; des fichiers touchés.&lt;br /&gt;
&lt;br /&gt;
Naviguez l&#039;application sur Heroku&lt;br /&gt;
&lt;br /&gt;
=Séance 3: Builders=&lt;br /&gt;
Les builders permettent d&#039;automatiser l&#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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; ([https://github.com/donsez/tagl https://github.com/donsez/tagl]) dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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 &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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 &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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 &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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 &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Séance 4: AOP &amp;amp; AspectJ=&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&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&#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 &#039;&#039;dev&#039;&#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&#039;une variable&lt;br /&gt;
* Les méthodes d&#039;une classe ont toute comme premier paramètre &#039;&#039;self&#039;&#039;, équivalent du &#039;&#039;this&#039;&#039; en Java.&lt;br /&gt;
* Blocs définis par indentation (4 espaces ou 1 tab)&lt;br /&gt;
* Une ligne finissant par &#039;:&#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;
# Import d&#039;un module&lt;br /&gt;
import pelix&lt;br /&gt;
&lt;br /&gt;
# Définition d&#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 &#039;&#039;pong.py&#039;&#039;, définissant une classe &#039;&#039;Pong&#039;&#039; ayant une méthode &#039;&#039;pong&#039;&#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 &#039;&#039;ping.py&#039;&#039;, définissant une classe &#039;&#039;Ping&#039;&#039; ayant une méthode &#039;&#039;ping&#039;&#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 &#039;&#039;pong.py&#039;&#039; pour qu&#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 &#039;&#039;Activator&#039;&#039;, décorée avec &#039;&#039;@BundleActivator&#039;&#039;&lt;br /&gt;
* Enregistrer le service dans la méthode &#039;&#039;Activator.start&#039;&#039; et le désenregistrer dans &#039;&#039;Activator.stop&#039;&#039;&lt;br /&gt;
* S&#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 &#039;pong&#039; et vérifier que le service est bien inscrit avec la commande &#039;&#039;sl&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
4.Transformer la classe &#039;&#039;Ping&#039;&#039; dans &#039;&#039;ping.py&#039;&#039; en un composant iPOPO&lt;br /&gt;
* L&#039;objet Pong utilisé dans &#039;&#039;ping()&#039;&#039; doit être un service injecté par iPOPO (&#039;&#039;@Requires&#039;&#039;)&lt;br /&gt;
* Appeler la méthode &#039;&#039;ping()&#039;&#039; dès que le service Pong est injecté (&#039;&#039;@BindField&#039;&#039;) ou disparait (&#039;&#039;@UnbindField&#039;&#039;)&lt;br /&gt;
* S&#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 &#039;ping&#039; et vérifier son comportement si le bundle &#039;&#039;pong&#039;&#039; ou le bundle &#039;&#039;ping&#039;&#039; est arrêté et redémarré.&lt;br /&gt;
&lt;br /&gt;
5. Mettre à jour le bundle &#039;&#039;pong&#039;&#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 &#039;&#039;pong&#039;&#039; sans redémarrer la plate-forme (commande &#039;&#039;udpate&#039;&#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&#039;export du service Pong dans &#039;&#039;pong.py&#039;&#039; (s&#039;inspirer de &#039;&#039;provider.py&#039;&#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;
** &#039;&#039;pelix.remote.dispatcher&#039;&#039;: Exportateur de services&lt;br /&gt;
** &#039;&#039;pelix.remote.registry&#039;&#039;; Importateur de services&lt;br /&gt;
** &#039;&#039;pelix.remote.discovery.multicast&#039;&#039;: Découverte de services via Multicast&lt;br /&gt;
** &#039;&#039;pelix.remote.xml_rpc&#039;&#039;: Transport XML-RPC&lt;br /&gt;
** &#039;&#039;pelix.http.basic&#039;&#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: &#039;&#039;instantiate pelix.http.service.basic.factory http-server pelix.http.port=8080&#039;&#039; (penser à changer de port dans chaque framework)&lt;br /&gt;
** Multicast Discovery: &#039;&#039;instantiate pelix-remote-discovery-multicast-factory multicast-discovery&#039;&#039;&lt;br /&gt;
** XML-RPC Exporter: &#039;&#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-exporter&#039;&#039;&lt;br /&gt;
** XML-RPC Importer: &#039;&#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-importer&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Installer le bundle &#039;&#039;ping&#039;&#039; dans un des frameworks et le bundle &#039;&#039;pong&#039;&#039; dans l&#039;autre.&lt;br /&gt;
* Le composant ping peut appeler le service pong, qui est dans l&#039;autre framework.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Voir le code de &#039;&#039;run_remote.py&#039;&#039; pour voir comment démarrer un framework Pelix et installer des bundles depuis Python.&lt;br /&gt;
* Jouer un peu avec &#039;&#039;run_remote.py&#039;&#039; (voir &#039;&#039;run_remote.py --help&#039;&#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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16646</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16646"/>
		<updated>2014-04-04T14:59:51Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Remote Services */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3: Pelix &amp;amp; iPOPO==&lt;br /&gt;
&lt;br /&gt;
Pelix est une plate-forme d&#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;
* Cloner le dépôt Git depuis https://github.com/tcalmant/ipopo&lt;br /&gt;
* Se placer dans la branche &#039;&#039;dev&#039;&#039;&lt;br /&gt;
* Pour installer iPOPO, 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&#039;une variable&lt;br /&gt;
* Les méthodes d&#039;une classe ont toute comme premier paramètre &#039;&#039;self&#039;&#039;, équivalent du &#039;&#039;this&#039;&#039; en Java.&lt;br /&gt;
* Blocs définis par indentation (4 espaces ou 1 tab)&lt;br /&gt;
* Une ligne finissant par &#039;:&#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;
# Import d&#039;un module&lt;br /&gt;
import pelix&lt;br /&gt;
&lt;br /&gt;
# Définition d&#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 &#039;&#039;pong.py&#039;&#039;, définissant une classe &#039;&#039;Pong&#039;&#039; ayant une méthode &#039;&#039;pong&#039;&#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 &#039;&#039;ping.py&#039;&#039;, définissant une classe &#039;&#039;Ping&#039;&#039; ayant une méthode &#039;&#039;ping&#039;&#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 &#039;&#039;pong.py&#039;&#039; pour qu&#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 &#039;&#039;Activator&#039;&#039;, décorée avec &#039;&#039;@BundleActivator&#039;&#039;&lt;br /&gt;
* Enregistrer le service dans la méthode &#039;&#039;Activator.start&#039;&#039; et le désenregistrer dans &#039;&#039;Activator.stop&#039;&#039;&lt;br /&gt;
* S&#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 &#039;pong&#039; et vérifier que le service est bien inscrit avec la commande &#039;&#039;sl&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
4.Transformer la classe &#039;&#039;Ping&#039;&#039; dans &#039;&#039;ping.py&#039;&#039; en un composant iPOPO&lt;br /&gt;
* L&#039;objet Pong utilisé dans &#039;&#039;ping()&#039;&#039; doit être un service injecté par iPOPO (&#039;&#039;@Requires&#039;&#039;)&lt;br /&gt;
* Appeler la méthode &#039;&#039;ping()&#039;&#039; dès que le service Pong est injecté (&#039;&#039;@BindField&#039;&#039;) ou disparait (&#039;&#039;@UnbindField&#039;&#039;)&lt;br /&gt;
* S&#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 &#039;ping&#039; et vérifier son comportement si le bundle &#039;&#039;pong&#039;&#039; ou le bundle &#039;&#039;ping&#039;&#039; est arrêté et redémarré.&lt;br /&gt;
&lt;br /&gt;
5. Mettre à jour le bundle &#039;&#039;pong&#039;&#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 &#039;&#039;pong&#039;&#039; sans redémarrer la plate-forme (commande &#039;&#039;udpate&#039;&#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&#039;export du service Pong dans &#039;&#039;pong.py&#039;&#039; (s&#039;inspirer de &#039;&#039;provider.py&#039;&#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;
** &#039;&#039;pelix.remote.dispatcher&#039;&#039;: Exportateur de services&lt;br /&gt;
** &#039;&#039;pelix.remote.registry&#039;&#039;; Importateur de services&lt;br /&gt;
** &#039;&#039;pelix.remote.discovery.multicast&#039;&#039;: Découverte de services via Multicast&lt;br /&gt;
** &#039;&#039;pelix.remote.xml_rpc&#039;&#039;: Transport XML-RPC&lt;br /&gt;
** &#039;&#039;pelix.http.basic&#039;&#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: &#039;&#039;instantiate pelix.http.service.basic.factory http-server pelix.http.port=8080&#039;&#039; (penser à changer de port dans chaque framework)&lt;br /&gt;
** Multicast Discovery: &#039;&#039;instantiate pelix-remote-discovery-multicast-factory multicast-discovery&#039;&#039;&lt;br /&gt;
** XML-RPC Exporter: &#039;&#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-exporter&#039;&#039;&lt;br /&gt;
** XML-RPC Importer: &#039;&#039;instantiate pelix-xmlrpc-exporter-factory xml-rpc-importer&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Installer le bundle &#039;&#039;ping&#039;&#039; dans un des frameworks et le bundle &#039;&#039;pong&#039;&#039; dans l&#039;autre.&lt;br /&gt;
* Le composant ping peut appeler le service pong, qui est dans l&#039;autre framework.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Voir le code de &#039;&#039;run_remote.py&#039;&#039; pour voir comment démarrer un framework Pelix et installer des bundles depuis Python.&lt;br /&gt;
* Jouer un peu avec &#039;&#039;run_remote.py&#039;&#039; (voir &#039;&#039;run_remote.py --help&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16645</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16645"/>
		<updated>2014-04-04T14:49:35Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Service Ping-Pong */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3: Pelix &amp;amp; iPOPO==&lt;br /&gt;
&lt;br /&gt;
Pelix est une plate-forme d&#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;
* Cloner le dépôt Git depuis https://github.com/tcalmant/ipopo&lt;br /&gt;
* Se placer dans la branche &#039;&#039;dev&#039;&#039;&lt;br /&gt;
* Pour installer iPOPO, 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&#039;une variable&lt;br /&gt;
* Les méthodes d&#039;une classe ont toute comme premier paramètre &#039;&#039;self&#039;&#039;, équivalent du &#039;&#039;this&#039;&#039; en Java.&lt;br /&gt;
* Blocs définis par indentation (4 espaces ou 1 tab)&lt;br /&gt;
* Une ligne finissant par &#039;:&#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;
# Import d&#039;un module&lt;br /&gt;
import pelix&lt;br /&gt;
&lt;br /&gt;
# Définition d&#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 &#039;&#039;pong.py&#039;&#039;, définissant une classe &#039;&#039;Pong&#039;&#039; ayant une méthode &#039;&#039;pong&#039;&#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 &#039;&#039;ping.py&#039;&#039;, définissant une classe &#039;&#039;Ping&#039;&#039; ayant une méthode &#039;&#039;ping&#039;&#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 &#039;&#039;pong.py&#039;&#039; pour qu&#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 &#039;&#039;Activator&#039;&#039;, décorée avec &#039;&#039;@BundleActivator&#039;&#039;&lt;br /&gt;
* Enregistrer le service dans la méthode &#039;&#039;Activator.start&#039;&#039; et le désenregistrer dans &#039;&#039;Activator.stop&#039;&#039;&lt;br /&gt;
* S&#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 &#039;pong&#039; et vérifier que le service est bien inscrit avec la commande &#039;&#039;sl&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
4.Transformer la classe &#039;&#039;Ping&#039;&#039; dans &#039;&#039;ping.py&#039;&#039; en un composant iPOPO&lt;br /&gt;
* L&#039;objet Pong utilisé dans &#039;&#039;ping()&#039;&#039; doit être un service injecté par iPOPO (&#039;&#039;@Requires&#039;&#039;)&lt;br /&gt;
* Appeler la méthode &#039;&#039;ping()&#039;&#039; dès que le service Pong est injecté (&#039;&#039;@BindField&#039;&#039;) ou disparait (&#039;&#039;@UnbindField&#039;&#039;)&lt;br /&gt;
* S&#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 &#039;ping&#039; et vérifier son comportement si le bundle &#039;&#039;pong&#039;&#039; ou le bundle &#039;&#039;ping&#039;&#039; est arrêté et redémarré.&lt;br /&gt;
&lt;br /&gt;
5. Mettre à jour le bundle &#039;&#039;pong&#039;&#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 &#039;&#039;pong&#039;&#039; sans redémarrer la plate-forme (commande &#039;&#039;udpate&#039;&#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;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16634</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16634"/>
		<updated>2014-04-04T14:10:05Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Rappels de Python */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3: Pelix &amp;amp; iPOPO==&lt;br /&gt;
&lt;br /&gt;
Pelix est une plate-forme d&#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;
* Cloner le dépôt Git depuis https://github.com/tcalmant/ipopo&lt;br /&gt;
* Se placer dans la branche &#039;&#039;dev&#039;&#039;&lt;br /&gt;
* Pour installer iPOPO, 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&#039;une variable&lt;br /&gt;
* Les méthodes d&#039;une classe ont toute comme premier paramètre &#039;&#039;self&#039;&#039;, équivalent du &#039;&#039;this&#039;&#039; en Java.&lt;br /&gt;
* Blocs définis par indentation (4 espaces ou 1 tab)&lt;br /&gt;
* Une ligne finissant par &#039;:&#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;
# Import d&#039;un module&lt;br /&gt;
import pelix&lt;br /&gt;
&lt;br /&gt;
# Définition d&#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;
===Remote Services===&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16633</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=16633"/>
		<updated>2014-04-04T13:59:10Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3: Pelix &amp;amp; iPOPO==&lt;br /&gt;
&lt;br /&gt;
Pelix est une plate-forme d&#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;
* Cloner le dépôt Git depuis https://github.com/tcalmant/ipopo&lt;br /&gt;
* Se placer dans la branche &#039;&#039;dev&#039;&#039;&lt;br /&gt;
* Pour installer iPOPO, 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;
===Service Ping-Pong===&lt;br /&gt;
&lt;br /&gt;
===Remote Services===&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=SmartCampus2014/Tutoriels&amp;diff=16316</id>
		<title>SmartCampus2014/Tutoriels</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=SmartCampus2014/Tutoriels&amp;diff=16316"/>
		<updated>2014-03-25T15:51:57Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Subscribe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Liens =&lt;br /&gt;
&lt;br /&gt;
* [http://air.imag.fr/index.php/SmartCampus2014 Présentation] du projet SmartCampus&lt;br /&gt;
* [http://air.imag.fr/index.php/SmartCampus2014/FicheSuivi Fiche de suivi] du projet&lt;br /&gt;
* [http://air.imag.fr/index.php/SmartCampus2014/CDC Cahier des charges]&lt;br /&gt;
&lt;br /&gt;
= Mosquitto =&lt;br /&gt;
&lt;br /&gt;
[[File:logo_mqtt.png | 200px| left]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Mosquitto est une implémentation de MQTT, un protocole de M2M de type publish-subscribe.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
* Documentation officielle : [http://mosquitto.org/documentation/]&lt;br /&gt;
* Pour Debian/Ubuntu et dérivés: [http://mosquitto.org/2013/01/mosquitto-debian-repository/]&lt;br /&gt;
* Ensuite télécharger le client en ligne de commande:&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install mosquitto python-mosquitto&lt;br /&gt;
sudo apt-get install mosquitto-clients&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Exemple de communication ==&lt;br /&gt;
* Dans un premier terminal on lance le broker :&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
&amp;gt;mosquitto&lt;br /&gt;
1391181009: mosquitto version 1.2.3 (build date 2013-12-04 21:22:55+0000) starting&lt;br /&gt;
1391181009: Using default config.&lt;br /&gt;
1391181009: Opening ipv4 listen socket on port 1883.&lt;br /&gt;
1391181009: Opening ipv6 listen socket on port 1883.&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Sur certaines distributions, mosquitto peut se trouver dans /usr/sbin/.&lt;br /&gt;
&lt;br /&gt;
* Dans un second terminal on crée un topic &amp;quot;toto&amp;quot; sur lequel on publie des messages.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mosquitto_sub -d -t toto &lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Dans un dernier terminal on publie sur le topic &amp;quot;toto&amp;quot;.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mosquitto_pub  -t toto -m &amp;quot;Hello world &amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Pour communiquer entre différents devices, il faut lancer le broker sur chacun d&#039;eux, puis indiquer lors du subscribe l&#039;adresse IP du publisher. Par exemple :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mosquitto_sub -d -h 192.168.0.1 -t toto &lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Comment utiliser openHAB avec Mosquitto ? =&lt;br /&gt;
[[File:logo_openhab.png | 200px| left]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Requis ==&lt;br /&gt;
Il faut en premier lieu ajouter le bundle MQTT bindings (disponible [http://code.google.com/p/openhab/downloads/detail?name=openhab-addons-1.3.1.zip&amp;amp;can=2&amp;amp;q= ici]) dans le dossier &amp;quot;addons&amp;quot; du runtime openHAB.&lt;br /&gt;
&lt;br /&gt;
Ne pas oublier de lancer le broker Mosquitto (commande mosquitto).&lt;br /&gt;
&lt;br /&gt;
Ajouter l&#039;URL du broker dans le fichier de configuration d&#039;openHAB (e.g. openhab.cfg) :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
mqtt:mosquitto.url=tcp://localhost:1883&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Subscribe ==&lt;br /&gt;
Lier un item à un topic en indiquant l&#039;alias du broker, le type des messages transmis, et l&#039;action effectuée sur openHAB sur réception des messages :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
{ mqtt=&amp;quot;&amp;lt;[&amp;lt;broker&amp;gt;:&amp;lt;topic&amp;gt;:&amp;lt;type&amp;gt;:&amp;lt;transformation&amp;gt;]&amp;quot; }&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
où &amp;lt;type&amp;gt; est soit &amp;quot;command&amp;quot; soit &amp;quot;state&amp;quot; (pour l&#039;update), et où &amp;lt;transformation&amp;gt; est &amp;quot;default&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Number Temperature_GF_Corridor 	&amp;quot;Temperature [%.1f °C]&amp;quot;	&amp;lt;temperature&amp;gt;	(Temperature, GF_Corridor) { mqtt=&amp;quot;&amp;lt;[mosquitto:temperature:state:default]&amp;quot; }&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
On peut alors publier avec &amp;quot;mosquitto_pub&amp;quot; sur le topic défini (e.g. &amp;quot;temperature&amp;quot;) et voir le changement dans l&#039;interface openHAB.&lt;br /&gt;
&lt;br /&gt;
== Publish ==&lt;br /&gt;
&lt;br /&gt;
Le principe  est relativement semblable. On lance &amp;quot;mosquitto_sub&amp;quot; sur le topic voulu (e.g. &amp;quot;light&amp;quot;).&lt;br /&gt;
Lier un item à un topic en indiquant l&#039;alias du broker, le type des messages transmis, le déclencheur de l&#039;envoi de message, et la transformation :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
{ mqtt=&amp;quot;&amp;gt;[&amp;lt;broker&amp;gt;:&amp;lt;topic&amp;gt;:&amp;lt;type&amp;gt;:&amp;lt;trigger&amp;gt;:&amp;lt;transformation&amp;gt;]&amp;quot; }&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Par exemple :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Switch Light_Outdoor_Garage &amp;quot;Garage&amp;quot; (Outdoor, Lights)  { mqtt=&amp;quot;&amp;gt;[mosquitto:light:command:ON:1],&amp;gt;[mosquitto:light:command:OFF:0]&amp;quot; }&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Ici, lorsque l&#039;interrupteur de la lumière du garage est actionné, le subscriber Mosquitto reçoit 0 ou 1.&lt;br /&gt;
&lt;br /&gt;
Pour plus d&#039;informations, voir le wiki officiel [https://github.com/openhab/openhab/wiki/MQTT-Binding ici].&lt;br /&gt;
&lt;br /&gt;
= Comment se connecter en SSH à la carte Galileo =&lt;br /&gt;
[[File:logo_arduino.png | 100px| left]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Voir le tutoriel officiel d&#039;Intel : [[Media:Galileo_GettingStarted.pdf | Galileo_GettingStarted.pdf]]&lt;br /&gt;
&lt;br /&gt;
== Configuration de la carte Galileo ==&lt;br /&gt;
* Avant tout, il est important de toujours alimenter la carte Galileo avant de la brancher à l’ordinateur !&lt;br /&gt;
* Connecter le Galileo à l’ordinateur avec le câble USB (port USB client de la carte).&amp;lt;br&amp;gt;&lt;br /&gt;
* Lancer l&#039;IDE Arduino et sélectionner le port série (Outils &amp;gt; Port série). Si le port série n&#039;est pas reconnu, essayez de relancer l&#039;IDE en Administrateur.&lt;br /&gt;
* Updater le firmware via l’IDE Arduino (Aide &amp;gt; Firmware Update). Cette étape est primordiale pour pouvoir se connecter en SSH. Il est aussi important de ne pas lancer de sketchs avant ou pendant la mise à jour.&lt;br /&gt;
* Créer un nouveau sketch :&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void setup() {&lt;br /&gt;
  // put your setup code here, to run once:&lt;br /&gt;
  system(&amp;quot;telnetd -l /bin/sh&amp;quot;);&lt;br /&gt;
  system(&amp;quot;ifconfig eth0 169.254.1.1 netmask 255.255.0.0 up&amp;quot;); //adapter l’adresse ip et le masque&lt;br /&gt;
  system(&amp;quot;route add default gw 169.254.1.2&amp;quot;); // le PC devient passerelle par défaut&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // put your main code here, to run repeatedly: &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Attention, il faut garder la boucle &#039;&#039;loop&#039;&#039; dans le code, même vide, pour ne pas avoir d&#039;erreur.  Dans cet exemple, nous lançons le service Telnet mais si on utilise seulement SSH, cette ligne n&#039;est pas nécessaire.&lt;br /&gt;
&lt;br /&gt;
* Flasher ce code sur la carte Galileo.&lt;br /&gt;
&lt;br /&gt;
* Configurer le PC en mode routeur (en root sous Linux) :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sysctl net.ipv4.ip_forward=1&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Activer le NAT sur le PC (en root sous Linux) :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE&lt;br /&gt;
iptables -A FORWARD -i wlan0 -o eth0:avahi -m state --state RELATED,ESTABLISHED -j ACCEPT&lt;br /&gt;
iptables -A FORWARD -i eth0:avahi -o wlan0 -j ACCEPT&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Sur Galileo, si la résolution d&#039;adresse ne fonctionne pas (e.g. ping www.google.com ne marche pas), configurer le DNS en ajoutant à /etc/resolv.conf :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
domain grenet.fr&lt;br /&gt;
search grenet.fr&lt;br /&gt;
nameserver 130.190.190.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Attention&amp;lt;/b&amp;gt; : les domaines ci-dessus sont valables seulement pour un PC connecté à wifi-campus. Sur un autre réseau, il suffit (sur un système UNIX) de copier le contenu de /etc/resolv.conf&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Connexion en SSH ==&lt;br /&gt;
* Relier le Galileo à l’ordinateur avec le câble Ethernet.&lt;br /&gt;
* Sur windows la connexion se fera automatiquement, mais sur Linux il faut changer l’adresse IP de la carte Ethernet pour être sur le même réseau que le Galileo :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo ifconfig eth0 169.254.1.2 up&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Faire un ping vers l’adresse ip 169.254.1.1 pour vérifier que la connexion fonctionne (si cela ne marche pas, il peut être judicieux de déconnecter la prise secteur de la carte et de la rebrancher).&lt;br /&gt;
&lt;br /&gt;
* Lorsque le ping fonctionne, il est possible de se connecter en root à la carte Galileo, soit en utilisant un client SSH de type PuTTY, ou via la commande :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ssh root@169.254.1.1&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Mis en place d&#039;une base de donnée mongodb (en local) =&lt;br /&gt;
[[File:logo_mongodb.png | 200px| left]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [http://docs.mongodb.org/manual/installation/ Installation et lancement] == &lt;br /&gt;
&lt;br /&gt;
Par la suite il est possible d&#039;accéder à différentes informations de votre BD via l&#039;url : &lt;br /&gt;
* http://localhost:28017/&lt;br /&gt;
&lt;br /&gt;
== Accéder au contenu ==&lt;br /&gt;
&lt;br /&gt;
Pour accéder au contenu d&#039;une collection de votre base de donnée, lancer la base de donnée en utilisant la commande :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo mongod --rest&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
puis dans votre navigateur, accéder à l&#039;URL :&lt;br /&gt;
* http://localhost:28017/nomDeVotreBD/nomDeVotreCollection/&lt;br /&gt;
&lt;br /&gt;
== Ajouter une base de donnée == &lt;br /&gt;
&lt;br /&gt;
Pour ajouter une base de donnée lancer mongo en version shell :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mongo&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Pour visualiser l&#039;ensemble des bases de données :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
show dbs&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Afin de créer une base de donnée ou se connecter à l&#039;une d&#039;elle : &lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
use nomBD&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Mise en place NodeJs Mongoose =&lt;br /&gt;
&lt;br /&gt;
== Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Effectuer le point précédent&lt;br /&gt;
Lancer les commandes :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo npm install express mongoose mongoose-schema-extend express-restify-mongoose&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Connexion à la BD ==&lt;br /&gt;
&lt;br /&gt;
* Afin de se connecter à la BD réalisée précédemment :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//Connection to the a mongodb database path localhost:port/nameOfDB&lt;br /&gt;
mongoose.connect(&amp;quot;mongodb://localhost:27017/Client&amp;quot;, function(err) {&lt;br /&gt;
    if (err) {&lt;br /&gt;
        throw err;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
* On définit le schéma d&#039;une collection en définissant son id et un champs &lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//Definition of a schema&lt;br /&gt;
var Temperature = new Schema({&lt;br /&gt;
    _id: Number,&lt;br /&gt;
    temp: Number&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Création du modèle&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var TemperatureModel = mongoose.model(&#039;temperature&#039;, Temperature);&lt;br /&gt;
&lt;br /&gt;
//Creation of an object which respect the model define before&lt;br /&gt;
var myTemperatureModel = new TemperatureModel({_id: 1473, temp: 16});&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Ajout d&#039;un élèment dans la base de donnée.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
//saved the temperature in the mongodb database&lt;br /&gt;
myTemperatureModel.save(function(err){&lt;br /&gt;
  if (err) { throw err; }&lt;br /&gt;
  console.log(&#039;Commentaire ajouté avec succès !&#039;);&lt;br /&gt;
  // On se déconnecte de MongoDB maintenant&lt;br /&gt;
  mongoose.connection.close();&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Mise en place NodeJs Mongoose MQTT =&lt;br /&gt;
&lt;br /&gt;
== Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Installation de mqtt&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
npm install mqtt&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
On fait appel à la librairie mqtt : &lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var mqtt = require(&#039;mqtt&#039;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Connexion au broker sur le port 1883 :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
client = mqtt.createClient(1883, &#039;localhost&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
On subscribe au topic &#039;temperature&#039;, et à chaque réception de ce topic on affiche ce qui a été reçu dans la console:&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
client.subscribe(&#039;temperature&#039;);&lt;br /&gt;
client.on(&#039;message&#039;, function (topic, message) {&lt;br /&gt;
  console.log(message);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
On peut également publier sur le topic &#039;light&#039; l&#039;info &#039;On&#039; :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
client.publish(&#039;light&#039;, &#039;On&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
En lançant ces commandes le texte &#039;On&#039; devrait apparaître sur votre console.&lt;br /&gt;
&lt;br /&gt;
= Utilisation de NodeJS Mongoose MQTT et Mosquitto =&lt;br /&gt;
&lt;br /&gt;
== Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Suivre le tuto sur mosquitto, NodeJS Mongoose MQTT et Mosquitto.&lt;br /&gt;
Lancer MongoDB.&lt;br /&gt;
Ajouter une DB dans mongo &amp;quot;Client&amp;quot; (cf tuto NodeJS Mongoose MQTT).&lt;br /&gt;
&lt;br /&gt;
== Test == &lt;br /&gt;
&lt;br /&gt;
Dans le .js Node ajouter le code suivant : &lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var http = require(&#039;http&#039;);&lt;br /&gt;
var express = require(&#039;express&#039;);&lt;br /&gt;
var mongoose = require(&#039;mongoose&#039;);&lt;br /&gt;
var mqtt = require(&#039;mqtt&#039;)&lt;br /&gt;
var Schema = mongoose.Schema;&lt;br /&gt;
var restify = require(&#039;express-restify-mongoose&#039;)&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////&lt;br /&gt;
/////// MONGODB  //////////////////&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
//Connection to the a mongodb database path localhost:port/nameOfCollection&lt;br /&gt;
mongoose.connect(&amp;quot;mongodb://localhost:27017/Client&amp;quot;, function(err) {&lt;br /&gt;
    if (err) {&lt;br /&gt;
        throw err;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
//Definition of a schema&lt;br /&gt;
var Temperature = new Schema({&lt;br /&gt;
    _id: Number,&lt;br /&gt;
    temp: Number&lt;br /&gt;
});&lt;br /&gt;
//Creation of the model&lt;br /&gt;
var TemperatureModel = mongoose.model(&#039;temperatures&#039;, Temperature);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////&lt;br /&gt;
/////// MQTT  //////////////////&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
client = mqtt.createClient(1883, &#039;localhost&#039;);&lt;br /&gt;
&lt;br /&gt;
client.subscribe(&#039;temperature&#039;);&lt;br /&gt;
&lt;br /&gt;
var i = 0;&lt;br /&gt;
client.on(&#039;message&#039;, function(topic, message) {&lt;br /&gt;
    console.log(message);&lt;br /&gt;
    var myTemperatureModel = new TemperatureModel({_id: i++, temp: message});&lt;br /&gt;
    myTemperatureModel.save(function(err) {&lt;br /&gt;
        if (err) {&lt;br /&gt;
            throw err;&lt;br /&gt;
        }&lt;br /&gt;
        console.log(&#039;Température ajouté à la BD avec succès !&#039;);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var app = express();&lt;br /&gt;
app.configure(function() {&lt;br /&gt;
    app.use(express.bodyParser());&lt;br /&gt;
    app.use(express.methodOverride());&lt;br /&gt;
    restify.serve(app, TemperatureModel);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Run the server&lt;br /&gt;
http.createServer(app).listen(4242, function() {&lt;br /&gt;
    console.log(&amp;quot;Express server listening on port 4242&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Lancer ceci avec Node.&lt;br /&gt;
&lt;br /&gt;
Lancer mosquitto et publier sur le topic &#039;light&#039; : &lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mosquitto&lt;br /&gt;
mosquitto_pub  -t temperature -m &amp;quot;25&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Par la suite, vous devriez voir le message &amp;quot;25°C&amp;quot; dans la console. &lt;br /&gt;
De plus, à l&#039;adresse http://localhost:28017/Client/temperatures/ vous devriez apercevoir l&#039;ajout d&#039;un objet JSON contenant en paramètre &#039;temp&#039; à 25.&lt;br /&gt;
&lt;br /&gt;
= Carte interactive =&lt;br /&gt;
&lt;br /&gt;
== Google Maps ==&lt;br /&gt;
[[File:logo_maps.png | 75px| left]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Voir la [https://developers.google.com/maps/documentation/javascript/reference?hl=FR documentation de l&#039;API].&lt;br /&gt;
&lt;br /&gt;
* Intégrer la carte :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
            html { height: 100% }&lt;br /&gt;
            body { height: 100%; margin: 0; padding: 0 }&lt;br /&gt;
            #map-canvas { height: 100% }&lt;br /&gt;
        &amp;lt;/style&amp;gt;&lt;br /&gt;
        &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://maps.google.com/maps/api/js?sensor=false&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
        &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
            function initialize() {&lt;br /&gt;
                var mapOptions = {&lt;br /&gt;
                    center: new google.maps.LatLng(45.19091427, 5.76828361), // centrer sur le campus de SMH&lt;br /&gt;
                    zoom: 15,&lt;br /&gt;
                    mapTypeId: google.maps.MapTypeId.ROADMAP&lt;br /&gt;
                };&lt;br /&gt;
                var map = new google.maps.Map(document.getElementById(&amp;quot;map-canvas&amp;quot;),&lt;br /&gt;
                        mapOptions);&lt;br /&gt;
&lt;br /&gt;
                // bounds of the desired area&lt;br /&gt;
                var allowedBounds = new google.maps.LatLngBounds( // limites du campus&lt;br /&gt;
                  new google.maps.LatLng(45.18575736, 5.75114965),&lt;br /&gt;
                  new google.maps.LatLng(45.20112086, 5.78054667)&lt;br /&gt;
                );&lt;br /&gt;
                var boundLimits = {&lt;br /&gt;
                    maxLat : allowedBounds.getNorthEast().lat(),&lt;br /&gt;
                    maxLng : allowedBounds.getNorthEast().lng(),&lt;br /&gt;
                    minLat : allowedBounds.getSouthWest().lat(),&lt;br /&gt;
                    minLng : allowedBounds.getSouthWest().lng()&lt;br /&gt;
                };&lt;br /&gt;
&lt;br /&gt;
                var lastValidCenter = map.getCenter();&lt;br /&gt;
                var newLat, newLng;&lt;br /&gt;
                google.maps.event.addListener(map, &#039;center_changed&#039;, function() {&lt;br /&gt;
                    center = map.getCenter();&lt;br /&gt;
                    if (allowedBounds.contains(center)) {&lt;br /&gt;
                        // still within valid bounds, so save the last valid position&lt;br /&gt;
                        lastValidCenter = map.getCenter();&lt;br /&gt;
                        return;&lt;br /&gt;
                    }&lt;br /&gt;
                    newLat = lastValidCenter.lat();&lt;br /&gt;
                    newLng = lastValidCenter.lng();&lt;br /&gt;
                    if(center.lng() &amp;gt; boundLimits.minLng &amp;amp;&amp;amp; center.lng() &amp;lt; boundLimits.maxLng){&lt;br /&gt;
                        newLng = center.lng();&lt;br /&gt;
                    }&lt;br /&gt;
                    if(center.lat() &amp;gt; boundLimits.minLat &amp;amp;&amp;amp; center.lat() &amp;lt; boundLimits.maxLat){&lt;br /&gt;
                        newLat = center.lat();&lt;br /&gt;
                    }&lt;br /&gt;
                    map.panTo(new google.maps.LatLng(newLat, newLng));&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
            google.maps.event.addDomListener(window, &#039;load&#039;, initialize);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;map-canvas&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* Ajouter un POI et une infobulle :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var latLng = new google.maps.LatLng(45.187778,5.726945);&lt;br /&gt;
&lt;br /&gt;
var marker = new google.maps.Marker({&lt;br /&gt;
    position : latLng,&lt;br /&gt;
    map      : map,&lt;br /&gt;
    title    : &amp;quot;titre&amp;quot;&lt;br /&gt;
    //icon     : &amp;quot;marker.gif&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
var infoWindow = new google.maps.InfoWindow({&lt;br /&gt;
    content  : &#039;infobulle&#039;,&lt;br /&gt;
    position : latLng&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Leaflet ==&lt;br /&gt;
&lt;br /&gt;
[[File:Leaflet_logo.png | 200px| left]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Voir la [http://leafletjs.com/reference.html documentation de l&#039;API].&lt;br /&gt;
&lt;br /&gt;
* Intégrer la carte (+ marqueurs et popups) :&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
	&amp;lt;title&amp;gt;Leaflet Example&amp;lt;/title&amp;gt;&lt;br /&gt;
	&amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;map&amp;quot; style=&amp;quot;width: 600px; height: 400px&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;script src=&amp;quot;http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;script&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        var map = L.map(&#039;map&#039;).setView([45.19091427, 5.76828361], 14);&lt;br /&gt;
	L.tileLayer(&#039;http://{s}.tile.cloudmade.com/ec5901144ac74caeb0bf17aeaeea442f/997/256/{z}/{x}/{y}.png&#039;, {&lt;br /&gt;
            attribution: &#039;&amp;amp;copy; &amp;lt;a href=&amp;quot;http://osm.org/copyright&amp;quot;&amp;gt;OpenStreetMap&amp;lt;/a&amp;gt; contributors&#039;,&lt;br /&gt;
            maxZoom: 18&lt;br /&gt;
        }).addTo(map);&lt;br /&gt;
        &lt;br /&gt;
        // add a marker&lt;br /&gt;
        var marker = L.marker([45.19, 5.77]).addTo(map);&lt;br /&gt;
        &lt;br /&gt;
        // add a circle&lt;br /&gt;
        var circle = L.circle([45.20, 5.76], 300, {&lt;br /&gt;
            color: &#039;red&#039;,&lt;br /&gt;
            fillColor: &#039;#f03&#039;,&lt;br /&gt;
            fillOpacity: 0.5&lt;br /&gt;
        }).addTo(map);&lt;br /&gt;
&lt;br /&gt;
        // add a polygon&lt;br /&gt;
        var polygon = L.polygon([&lt;br /&gt;
            [45.189, 5.765],&lt;br /&gt;
            [45.193, 5.762],&lt;br /&gt;
            [45.192, 5.750]&lt;br /&gt;
        ]).addTo(map);&lt;br /&gt;
&lt;br /&gt;
        // add popups        &lt;br /&gt;
        marker.bindPopup(&amp;quot;&amp;lt;b&amp;gt;Hello world!&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;I am a popup.&amp;quot;).openPopup();&lt;br /&gt;
        circle.bindPopup(&amp;quot;I am a circle.&amp;quot;);&lt;br /&gt;
        polygon.bindPopup(&amp;quot;I am a polygon.&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        // add a standalone popup&lt;br /&gt;
        var popup = L.popup()&lt;br /&gt;
            .setLatLng([45.185, 5.775])&lt;br /&gt;
            .setContent(&amp;quot;I am a standalone popup.&amp;quot;)&lt;br /&gt;
            .openOn(map);         &lt;br /&gt;
            &lt;br /&gt;
        // event&lt;br /&gt;
        function onMapClick(e) {&lt;br /&gt;
            popup&lt;br /&gt;
                .setLatLng(e.latlng)&lt;br /&gt;
                .setContent(&amp;quot;You clicked the map at &amp;quot; + e.latlng.toString())&lt;br /&gt;
                .openOn(map);&lt;br /&gt;
        }&lt;br /&gt;
        map.on(&#039;click&#039;, onMapClick);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;/script&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
= Installation d&#039;un OS basé sur Linux (LSB - Linux Standard Base) sur Intel Galileo =&lt;br /&gt;
&lt;br /&gt;
== Prérequis ==&lt;br /&gt;
&lt;br /&gt;
Avoir mis à jour le firmware.&lt;br /&gt;
&lt;br /&gt;
== Traitement sur sa carte SD == &lt;br /&gt;
&lt;br /&gt;
Suivre le tuto [https://communities.intel.com/thread/45852 ici] afin que la carte SD respecte le bon format.&lt;br /&gt;
&lt;br /&gt;
== Utilisation d&#039;un Linux sur la carte SD == &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention à l&#039;heure actuelle, en utilisant cette solution l&#039;IDE Arduino Galileo ne reconnaitra pas la carte Galileo&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Il existe deux solutions possibles pour installer un linux sur votre OS. La première consiste à créer votre propre OS sur mesure avec Yocto Project mais cela demande plus de 4h avec une machine ayant un i7 haswell (4700hq). Une autre solution est de télécharger les images pré-buildées qui pourraient correspondre à vos besoin. &lt;br /&gt;
&lt;br /&gt;
=== Créer votre propre OS sur mesure ===&lt;br /&gt;
&lt;br /&gt;
Grâce à ce pdf, pas à pas, il est expliqué comment réaliser son propre OS basé sur Linux.&lt;br /&gt;
[[File:IntelAcademic_IoT_26_IntelInside_Rebuild_Yocto_Reviewed.pdf]]&lt;br /&gt;
&lt;br /&gt;
=== OS pré-buildé ===&lt;br /&gt;
&lt;br /&gt;
Des OS pré-buildés sont également disponibles [http://ccc.ntu.edu.tw/index.php/en/news/40 ici] selon ce que vous voulez faire.&lt;br /&gt;
Une fois l&#039;une des archives téléchargées il suffit de le dézipper, et de le copier sur sa carte mini-SD. &lt;br /&gt;
Une fois ces commandes effectuées, il est possible d&#039;utiliser la carte en suivant ces instructions : &lt;br /&gt;
* Brancher le câble ethernet au routeur ;&lt;br /&gt;
* Mettre la mini carte SD ;&lt;br /&gt;
* Brancher la carte Galileo au secteur.&lt;br /&gt;
Sur la carte Galileo, l&#039;adresse IP de la carte Galileo est &amp;quot;settée&amp;quot; grâce au protocole DHCP, ce qui permet ainsi d&#039;y accéder en ssh une fois que l&#039;on a trouvé l&#039;adresse IP donnée à sa carte Galileo.&lt;br /&gt;
&lt;br /&gt;
=== Utilisation des sketchs ===&lt;br /&gt;
&lt;br /&gt;
La solution pour lancer des sketchs sur Galileo il faut utiliser les GPIO (General Purpose Input/Output) de la carte, via un langage de programmation.&lt;br /&gt;
Exemple : &lt;br /&gt;
*[https://github.com/agnathan/iot-mwc-samples langageC] &lt;br /&gt;
*[http://wiki.ros.org/IntelGalileo/IntelGalileoGPIO python].&lt;br /&gt;
&lt;br /&gt;
== Utilisation d&#039;un Debian ==&lt;br /&gt;
&lt;br /&gt;
Nous n&#039;avons pas testé l&#039;utilisation d&#039;un OS Debian car selon la communauté Intel, cela rendrait la carte trop lente.&lt;br /&gt;
&lt;br /&gt;
== Utilisation de Java, Openhab, Mosquitto ==&lt;br /&gt;
&lt;br /&gt;
* Effectuer ce qui est indiqué dans la section [http://air.imag.fr/index.php/SmartCampus2014/Tutoriels#OS_pr.C3.A9-build.C3.A9 OS-prébuildé] en téléchargeant le lien &amp;quot;Yocto Project Linux image w/ Clanton-full kernel + general SDKs + OpenJDK-6&amp;quot;.&lt;br /&gt;
* Se connecter en ssh à la carte Galileo&lt;br /&gt;
* Ajuster la date de la carte à celle de votre ordinateur avec la commande : &amp;quot;date DateSurOrdi&amp;quot; &lt;br /&gt;
* Depuis une autre console, copier le dossier &#039;&#039;openhab runtime&#039;&#039; sur la carte Galileo : &amp;quot;scp -r openhabruntime root@ipAdressGalileo:.&amp;quot;&lt;br /&gt;
* Télécharger les sources de mosquitto [http://mosquitto.org/download/ ici] &lt;br /&gt;
* Copier les sources mosquitto sur Galileo&lt;br /&gt;
* Les décompresser depuis ssh&lt;br /&gt;
* Accéder à ce dossier&lt;br /&gt;
* Effectuer la commande &#039;&#039;make&#039;&#039; &lt;br /&gt;
* Accéder à src/mosquitto.conf avec vi (ou votre éditeur préféré) et ajouter &#039;&#039;user root&#039;&#039;&lt;br /&gt;
* Lancer mosquitto : &amp;quot;./src/mosquitto -c src/mosquitto.conf&amp;quot;&lt;br /&gt;
* Lancer openhab : &amp;quot;sh start.sh&amp;quot;&lt;br /&gt;
* Après l&#039;affichage de &amp;quot;started classic UI at /openhab.app&amp;quot;, vous pouvez accéder à http://@ipGalileo:8080/openhab.app?sitemap=demo&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Création d&#039;une route personnalisée avec Express (framework node.js)  =&lt;br /&gt;
&lt;br /&gt;
==Prérequis==&lt;br /&gt;
* nodejs et Express installés&lt;br /&gt;
Installer nodejs et npm. [http://nodejs.org/]&lt;br /&gt;
Ensuite : &lt;br /&gt;
  npm install express&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Express est un framework Node.js MVC.&lt;br /&gt;
Il s&#039;organise autour de trois dossiers principaux : routes, views et public.&lt;br /&gt;
* views : regroupe l&#039;ensemble des vues ; dans notre présentation une simple page HTML.&lt;br /&gt;
* routes : le modèle où l&#039;on définit les fonctionnalités de chaque &amp;quot;route&amp;quot;&lt;br /&gt;
* public : rassemble les éléments statiques (js, css, ...)&lt;br /&gt;
&lt;br /&gt;
Une route désigne une adresse adresse:port/une/route/personnalisee.&lt;br /&gt;
&lt;br /&gt;
Le fichier principal fait office de contrôleur.&lt;br /&gt;
== Un hello world avec Express==&lt;br /&gt;
Un simple hello world avec Express.&lt;br /&gt;
&lt;br /&gt;
serveur.js&lt;br /&gt;
----------------&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var express = require(&#039;express&#039;);  // include express&lt;br /&gt;
var app = express();               // lance l&#039;application&lt;br /&gt;
&lt;br /&gt;
app.get(&#039;/&#039;, function(req, res){   // définit la route racine&lt;br /&gt;
  res.send(&#039;hello world&#039;);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
app.listen(4242);                  // ecoute sur le port 4242&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----------------&lt;br /&gt;
&lt;br /&gt;
Pour lancer l&#039;application &lt;br /&gt;
  nodejs serveur.js&lt;br /&gt;
  Allez sur http://localhost:4242/&lt;br /&gt;
&lt;br /&gt;
== Organiser le routage ==&lt;br /&gt;
L&#039;ensemble des routes peut être décrit dans le fichier principal serveur.js. Cependant pour plus de clarté les routes sont généralement définies dans le dossier /routes.&lt;br /&gt;
&lt;br /&gt;
serveur.js&lt;br /&gt;
----------------&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var express = require(&#039;express&#039;);  // include express&lt;br /&gt;
var routes = require(&#039;./routes&#039;);&lt;br /&gt;
var app = express();               // lance l&#039;application&lt;br /&gt;
&lt;br /&gt;
app.get(&#039;/&#039;, routes.hello);        // définit la route racine&lt;br /&gt;
app.get(&#039;/json&#039;, routes.exjson);        &lt;br /&gt;
app.get(&#039;/unepage&#039;, routes.unepage);    &lt;br /&gt;
&lt;br /&gt;
app.listen(4242);                  // ecoute sur le port 4242&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----------------&lt;br /&gt;
&lt;br /&gt;
/routes/index.js&lt;br /&gt;
----------------&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
exports.hello = function(req, res) {&lt;br /&gt;
    res.send(&amp;quot;&amp;lt;h1&amp;gt;Hello World !&amp;lt;/h1&amp;gt;&amp;quot;);&lt;br /&gt;
};&lt;br /&gt;
exports.unepage = function(req, res) {&lt;br /&gt;
    res.render(&#039;une_page.html&#039;);&lt;br /&gt;
}&lt;br /&gt;
exports.exjson = function(req, res) {&lt;br /&gt;
    res.json(200, {message: &amp;quot;Welcome in our site !&amp;quot;});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----------------&lt;br /&gt;
&lt;br /&gt;
views/une_page.html&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
	&amp;lt;title&amp;gt;Leaflet Example&amp;lt;/title&amp;gt;&lt;br /&gt;
	&amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
	Une simple page	&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15678</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15678"/>
		<updated>2014-02-21T13:48:20Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 2: AOP &amp;amp; AspectJ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s)&lt;br /&gt;
#: Affichez une trace avant et après l&#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&#039;exécution d&#039;une tâche au bout d&#039;une minute (pattern &amp;quot;* * * * *&amp;quot;)&lt;br /&gt;
#: Lors de l&#039;exécution de &#039;&#039;&#039;mvn test&#039;&#039;&#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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15666</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15666"/>
		<updated>2014-02-20T16:45:54Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 2: AOP &amp;amp; AspectJ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&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&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15665</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15665"/>
		<updated>2014-02-20T16:00:41Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2: AOP &amp;amp; AspectJ==&lt;br /&gt;
&lt;br /&gt;
Dans votre dépôt Git, projet &#039;&#039;cron4j-mvn&#039;&#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&#039;invocation des méthodes &#039;&#039;&#039;run()&#039;&#039;&#039; de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
&lt;br /&gt;
# Complétez l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15664</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15664"/>
		<updated>2014-02-20T15:58:23Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Contrôle Continu */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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 &#039;&#039;target/site/cobertura&#039;&#039;&lt;br /&gt;
## Le plugin ne s&#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;
## &#039;&#039;&#039;Bonus:&#039;&#039;&#039; Modifiez le fichier &#039;&#039;pom.xml&#039;&#039; pour que le &#039;&#039;goal&#039;&#039; &#039;&#039;&#039;cobertura&#039;&#039;&#039; soit exécuté pendant la &#039;&#039;phase&#039;&#039; &#039;&#039;&#039;package&#039;&#039;&#039;.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15663</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15663"/>
		<updated>2014-02-20T15:36:25Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Contrôle Continu */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#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 &#039;&#039;tagl&#039;&#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;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au projet Maven les plugins pour la génération d&#039;un site et de rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): voir http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15662</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15662"/>
		<updated>2014-02-20T15:33:35Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Git (suite) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que &#039;&#039;donsez/tagl&#039;&#039;)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. &#039;&#039;tagl-licensing&#039;&#039;)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. &#039;&#039;tagl-licensing&#039;&#039;)&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 &#039;&#039;pull request&#039;&#039; aura été accepté, vous pourrez supprimer votre fork (&#039;&#039;tagl-licensing&#039;&#039;) de votre compte GitHub.&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15661</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15661"/>
		<updated>2014-02-20T15:31:04Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Git (suite) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
&lt;br /&gt;
# Forkez le projet &#039;&#039;&#039;tagl&#039;&#039;&#039; d&#039;un autre binome (i.e. autre que donsez/tagl)&lt;br /&gt;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; donnez lui un nom différent (e.g. tagl-licensing)&lt;br /&gt;
# Clonez ce nouveau dépôt&lt;br /&gt;
# Lancez une compilation pour valider l&#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;
# Ajoutez une bannière de licence dans le fichier &#039;&#039;&#039;cron4j-mvn/pom.xml&#039;&#039;&#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. tagl-licensing)&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;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15660</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15660"/>
		<updated>2014-02-20T15:07:47Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Tests Unitaires avec JUnit 4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
# Ajouter le test unitaire suivant au projet, dans le fichier &#039;&#039;&#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 &#039;&#039;&#039;échouer&#039;&#039;&#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;
#: &#039;&#039;&#039;Attention:&#039;&#039;&#039; Travis va exécuter les tests &#039;&#039;dès que possible&#039;&#039;. Il est possible de recevoir un mail indiquant que les tests du premier &#039;&#039;push&#039;&#039; échouent alors que l&#039;on a déjà &#039;&#039;pushé&#039;&#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;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15657</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15657"/>
		<updated>2014-02-20T14:47:47Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Maven */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&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;
&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 &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec la structure Maven&lt;br /&gt;
# Dans ce dossier, utilisez l&#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):&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 &#039;&#039;pom.xml&#039;&#039;, et une classe et un test modèles: supprimez ces modèles&lt;br /&gt;
# Copiez les sources de Cron4J depuis le dossier &#039;&#039;&#039;cron4j-original&#039;&#039;&#039; dans le dossier &#039;&#039;&#039;src/main/java&#039;&#039;&#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;
# Enfin modifiez le fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; à la racine de votre dépôt Git afin que Travis exécute la commande &#039;&#039;&#039;mvn clean verify&#039;&#039;&#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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15639</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15639"/>
		<updated>2014-02-19T11:46:44Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Maven */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer un dossier &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039;: il contiendra le projet Cron4J avec le layout Maven, en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15638</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15638"/>
		<updated>2014-02-19T11:42:42Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* GitHub &amp;amp; Travis-CI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
# Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
# &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
# Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
# Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
# Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15637</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15637"/>
		<updated>2014-02-19T11:41:38Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* GitHub &amp;amp; Travis-CI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#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 (&#039;&#039;&#039;.travis.yml&#039;&#039;&#039;), mais il est possible d&#039;utiliser la commande &#039;&#039;&#039;sudo apt-get install ...&#039;&#039;&#039; pour ajouter vos dépendances.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
#. Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
#. &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
#. Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (&#039;&#039;settings&#039;&#039;) de ce projet&lt;br /&gt;
#. Pour l&#039;exemple, activez le service (ou hook) &#039;&#039;Email&#039;&#039; depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;&#039;git push&#039;&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
#. Activez le service Travis-CI: identifiez-vous (&#039;&#039;sign in&#039;&#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&#039;intégration continue&lt;br /&gt;
&lt;br /&gt;
Travis-CI utilise un fichier nommé &#039;&#039;&#039;.travis.yml&#039;&#039;&#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 &#039;&#039;&#039;Commit&#039;&#039;&#039; puis un &#039;&#039;&#039;Push&#039;&#039;&#039; du fichier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ce fichier indique que le projet dans ce dépôt doit être testé sur 3 versions de Java (Oracle Java 7, Open JDK 6 et Open JDK 7), et que le script à exécuter pour lancer les tests est &#039;&#039;&#039;pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&#039;&#039;&#039;.&lt;br /&gt;
Travis-CI peut exécuter plusieurs commandes dans script, chacune d&#039;entre elles devant démarrer par un &#039;-&#039; (élément dans une liste de &#039;scripts&#039;).&lt;br /&gt;
&lt;br /&gt;
Attention: il n&#039;est pas possible d&#039;utiliser &#039;&#039;&#039;cd&#039;&#039;&#039; pour changer de répertoire, il faut utiliser &#039;&#039;&#039;pushd&#039;&#039;&#039; (déplacement dans un dossier) et &#039;&#039;&#039;popd&#039;&#039;&#039; (retour au dossier précédent) à la place.&lt;br /&gt;
&lt;br /&gt;
Une fois ce fichier de configuration &#039;&#039;&#039;pushé&#039;&#039;&#039;, Travis-CI se mettra en route dès le prochain &#039;&#039;&#039;push&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15636</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15636"/>
		<updated>2014-02-19T11:32:26Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* GitHub &amp;amp; Travis-CI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
&lt;br /&gt;
Travis-CI est un service permettant d&#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&#039;intérêt est de savoir si la version d&#039;un projet que vous avez rendu publique peut être compilée et si ses tests passent.&lt;br /&gt;
&lt;br /&gt;
Pour utiliser Travis:&lt;br /&gt;
&lt;br /&gt;
#. Créez compte individuel sur GitHub https://github.com&lt;br /&gt;
#. &#039;&#039;Fork&#039;&#039;ez le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
#. Ajoutez un collaborateur (i.e. votre binôme) au projet &#039;&#039;forké&#039;&#039;, via les paramètres (//settings//) de ce projet&lt;br /&gt;
#. Pour l&#039;exemple, activez le service (ou hook) //Email// depuis les paramètres du dépôt: à chaque fois que vous ou un de vos collaborateurs ferra un &#039;&#039;git push&#039;&#039;, vous recevrez une notification par mail.&lt;br /&gt;
#. Activez le service Travis-CI: identifiez-vous (//sign in//) sur https://travis-ci.org/ avec votre compte GitHub&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15635</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15635"/>
		<updated>2014-02-19T11:25:27Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Méthode moins simple: bare first */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&#039;importance des README===&lt;br /&gt;
&lt;br /&gt;
Il est très important d&#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&#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&#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&#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;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur (ie votre binome) au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15634</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15634"/>
		<updated>2014-02-19T11:19:29Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Git */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
&lt;br /&gt;
Création d&#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&#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&#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&#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&#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&#039;URL pour accéder à ce dépôt est URL_REPO.&lt;br /&gt;
On va d&#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&#039;il s&#039;agit du dépôt &amp;quot;principal&amp;quot; à utiliser, on l&#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&#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 &#039;&#039;git push&#039;&#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&#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&#039;on clone un dépôt vide: le dépôt local à donc une branche master, mais elle n&#039;est pas liée au dépôt distant, car celui-ci n&#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&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;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur (ie votre binome) au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15633</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15633"/>
		<updated>2014-02-19T11:03:04Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Cherry-picking: reprise des modifications d&amp;#039;un collègue */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push origin master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur (ie votre binome) au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#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&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15632</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15632"/>
		<updated>2014-02-19T11:00:38Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Bonus Track */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push origin master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur (ie votre binome) au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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&#039;un collègue===&lt;br /&gt;
&lt;br /&gt;
On considère:&lt;br /&gt;
&lt;br /&gt;
* votre dépôt Git distant est à l&#039;adresse URL_DEPOT&lt;br /&gt;
* votre collègue a un dépôt Git à l&#039;adresse URL_COLLEGUE&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&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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&#039;activation se fait via &#039;&#039;Settings &amp;gt; Webhooks &amp;amp; Services &amp;gt; Configure services&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15477</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15477"/>
		<updated>2014-02-14T09:25:58Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Git */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push origin master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur (ie votre binome) au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
====Archetype webapp====&lt;br /&gt;
L&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15205</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15205"/>
		<updated>2014-02-07T08:01:23Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Tests Unitaires avec JUnit 4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Travaux pratiques de l&#039;UE [[TAGL]].&lt;br /&gt;
&lt;br /&gt;
==Séance 1==&lt;br /&gt;
===Git===&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
===GitHub &amp;amp; Travis-CI===&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur (ie votre binome) au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Maven===&lt;br /&gt;
[http://maven.apache.org/download.cgi Changer et installer Maven 3].&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;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml) en réorganisant les sources de cron4j-original. Pour cela, vous utiliserez préalablement un [https://maven.apache.org/guides/introduction/introduction-to-archetypes.html archetype Maven] &#039;&#039;simple&#039;&#039; ou &#039;&#039;quickstart&#039;&#039;. (la version de cron4j est la 2.5.5).&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&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;
Ajouter le test unitaire suivant au layout du projet&lt;br /&gt;
&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;
&lt;br /&gt;
Rechercher la dépendance JUnit 4 dans [http://search.maven.org/#search|ga|1|JUnit Maven Central]&lt;br /&gt;
&lt;br /&gt;
Ajouter la dépendance JUnit 4 au pom.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lancer le build mvn test&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Regarder votre mail box.&lt;br /&gt;
&lt;br /&gt;
Naviguer sur http://travis-ci.org pour vérifier les builds effectués.&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser&lt;br /&gt;
&lt;br /&gt;
===Git (suite)===&lt;br /&gt;
# Forker le projet &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; d&#039;un autre binome (ie l&#039;origine)&lt;br /&gt;
# Ajouter une bannière de licence dans le pom.xml&lt;br /&gt;
# Lancer mvn clean install (bonne pratique)&lt;br /&gt;
# Commiter&lt;br /&gt;
# Faire un Push request vers l&#039;origine&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
&lt;br /&gt;
Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
&lt;br /&gt;
Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
====Archetype webapp====&lt;br /&gt;
L&#039;archetype webapp (http://maven.apache.org/archetype/maven-archetype-bundles/maven-archetype-webapp/) permet de créer le squelette d&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@WIP&lt;br /&gt;
&lt;br /&gt;
Injection de dépendances avec [[Guice]]  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15189</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15189"/>
		<updated>2014-02-06T16:36:00Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Créer des tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean test&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15188</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15188"/>
		<updated>2014-02-06T16:35:11Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL &#039;&#039;&#039;cron4j&#039;&#039;&#039; depuis https://github.com/donsez/tagl&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15187</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15187"/>
		<updated>2014-02-06T16:34:30Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        - pushd cron4j-original &amp;amp;&amp;amp; ant rel &amp;amp;&amp;amp; popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15186</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15186"/>
		<updated>2014-02-06T16:14:58Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
Committer un fichier &#039;&#039;ci_run.sh&#039;&#039; exécutant les étapes de compilation (nécessaire afin de se placer dans le bon dossier)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Original (Ant)&amp;quot;&lt;br /&gt;
pushd cron4j-original&lt;br /&gt;
ant rel&lt;br /&gt;
popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant (depuis un gist)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
before_script:&lt;br /&gt;
        chmod +x ci_run.sh&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        ./ci_run.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15185</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15185"/>
		<updated>2014-02-06T16:12:50Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Clone SVN -&amp;gt; Git */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
Créer un fichier &#039;&#039;ci_run.sh&#039;&#039; exécutant les étapes de compilation (nécessaire afin de se placer dans le bon dossier)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Original (Ant)&amp;quot;&lt;br /&gt;
pushd cron4j-original&lt;br /&gt;
ant rel&lt;br /&gt;
popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant (depuis un gist)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
before_script:&lt;br /&gt;
        chmod +x ci_run.sh&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        ./ci_run.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15184</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15184"/>
		<updated>2014-02-06T16:12:37Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Préparation TAGL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
Créer un fichier &#039;&#039;ci_run.sh&#039;&#039; exécutant les étapes de compilation (nécessaire afin de se placer dans le bon dossier)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Original (Ant)&amp;quot;&lt;br /&gt;
pushd cron4j-original&lt;br /&gt;
ant rel&lt;br /&gt;
popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant (depuis un gist)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
before_script:&lt;br /&gt;
        chmod +x ci_run.sh&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        ./ci_run.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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;pre&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;/pre&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&#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;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15183</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15183"/>
		<updated>2014-02-06T16:07:42Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Séance 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
Créer un fichier &#039;&#039;ci_run.sh&#039;&#039; exécutant les étapes de compilation (nécessaire afin de se placer dans le bon dossier)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Original (Ant)&amp;quot;&lt;br /&gt;
pushd cron4j-original&lt;br /&gt;
ant rel&lt;br /&gt;
popd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant (depuis un gist)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
language: java&lt;br /&gt;
&lt;br /&gt;
jdk:&lt;br /&gt;
        - oraclejdk7&lt;br /&gt;
        - openjdk6&lt;br /&gt;
        - openjdk7&lt;br /&gt;
&lt;br /&gt;
before_script:&lt;br /&gt;
        chmod +x ci_run.sh&lt;br /&gt;
&lt;br /&gt;
script:&lt;br /&gt;
        ./ci_run.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajoutez au pom.xml le plugin Covertura pour la couverture de code.&lt;br /&gt;
# Répondez aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajoutez au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&lt;br /&gt;
# Pour la prochaine séance, regardez les exemples d&#039;utilisation de cron4j dans cron4j-original/examples&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;pre&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;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Préparation TAGL====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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&#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;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
AOP &amp;amp; AspectJ&lt;br /&gt;
&lt;br /&gt;
Ajouter le [http://mojo.codehaus.org/aspectj-maven-plugin/ plugin Maven pour AspectJ] au pom.xml&lt;br /&gt;
&lt;br /&gt;
Ajouter un aspect de trace à l&#039;invocation des méthodes run() de l&#039;interface java.lang.Runnable (uniquement pour les objets &#039;&#039;schedulé&#039;&#039;s).&lt;br /&gt;
&lt;br /&gt;
===Contrôle continu===&lt;br /&gt;
Compléter l&#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&#039;identifiant du job et 2) le compteur des appels de la méthode de l&#039;objet.&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
[[Tutorial OSGi avec Apache Felix]]&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Séance 5==&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>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15160</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15160"/>
		<updated>2014-02-06T11:04:55Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Clone SVN -&amp;gt; Git */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant (depuis un gist)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajouter au pom.xml le plugin Covertura pour la couverture de code. Répondre aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajouter au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&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;pre&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;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Préparation TAGL====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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&#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;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15159</id>
		<title>TAGL/TP</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=TAGL/TP&amp;diff=15159"/>
		<updated>2014-02-06T11:04:35Z</updated>

		<summary type="html">&lt;p&gt;Calmant: Ajout du Bonus Track&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Séance 1==&lt;br /&gt;
Créer un dépôt Git local (bare)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir tagl&lt;br /&gt;
cd tagl&lt;br /&gt;
mkdir testgit&lt;br /&gt;
cd testgit&lt;br /&gt;
git init --bare&lt;br /&gt;
cd ..&lt;br /&gt;
git clone testgit testgit-work&lt;br /&gt;
cd testgit-work&lt;br /&gt;
echo hello &amp;gt; readme.rst&lt;br /&gt;
git add readme.rst&lt;br /&gt;
git commit&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En parallèle : Installer dans votre Eclipse le plugin ReST Editor depuis le [https://marketplace.eclipse.org/content/rest-editor Marketplace Eclipse]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer compte individuel sur GitHub https://github.com&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Fork&#039;&#039;er le projet TAGL (url) &#039;&#039;&#039;cron4j&#039;&#039;&#039; (2.5.5)&lt;br /&gt;
&lt;br /&gt;
Ajouter un collaborateur au projet &#039;&#039;forké&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Activer le Email hook depuis les paramètres (settings) du dépôt.&lt;br /&gt;
&lt;br /&gt;
Activer le Travis-CI &#039;&#039;hook&#039; depuis https://travis-ci.org/ (sign in avec le compte GitHub)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Commit/Push&#039;&#039; &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour Ant (depuis un gist)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &#039;&#039;&#039;cron4j-mvn&#039;&#039;&#039; (layout + pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier .travis.yml pour &#039;&#039;mvn -DskipTests=true clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
Tests unitaires du i.s.c.CronParser (Ajouter la dépendance JUnit 4 au pom.xml)&lt;br /&gt;
&lt;br /&gt;
Modifier &#039;&#039;&#039;.travis.yml&#039;&#039;&#039; pour &#039;&#039;mvn clean install&#039;&#039; (Commit/Push)&lt;br /&gt;
&lt;br /&gt;
===Contrôle Continu===&lt;br /&gt;
# Ajouter au pom.xml le plugin Covertura pour la couverture de code. Répondre aux questions : &#039;&#039;Mais qu&#039;est ce que la couverture de code ? En quoi c&#039;est utile ?&#039;&#039;&lt;br /&gt;
# Ajouter au pom.xml les plugins pour la gestion du site et des rapports (Javadoc, tests unitaires, tags list (FIXME, TODO, ...), ...): http://maven.apache.org/plugins/maven-site-plugin/ et d&#039;autres.&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;pre&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;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Préparation TAGL&lt;br /&gt;
================&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&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&#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;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Séance 2==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
==Séance 3==&lt;br /&gt;
@TODO&lt;br /&gt;
&lt;br /&gt;
==Séance 4==&lt;br /&gt;
@TODO&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_2&amp;diff=11328</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 2</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_2&amp;diff=11328"/>
		<updated>2013-04-19T08:59:25Z</updated>

		<summary type="html">&lt;p&gt;Calmant: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
=Sources du TP=&lt;br /&gt;
&lt;br /&gt;
[https://dl.dropboxusercontent.com/u/66952950/tposgi.zip sources du TP]&lt;br /&gt;
&lt;br /&gt;
=TP OSGi Partie 2 : Composants OSGi=&lt;br /&gt;
&lt;br /&gt;
Vous manipulerez [http://felix.apache.org/site/apache-felix-ipojo.html Apache iPOJO] le modèle de composant orienté service Java pour OSGi utilisé industrielement&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
* Dézipper les sources du TP&lt;br /&gt;
* Changez &#039;&#039;&#039;EVENTUELLEMENT&#039;&#039;&#039; les valeurs du proxy dans le fichier tposgi\felix-framework\run.bat&lt;br /&gt;
* &amp;lt;strike&amp;gt;Installez EVENTUELLEMENT osgi-part2\settings.xml dans  C:\Documents and Settings\VotreUsername\.m2&amp;lt;/strike&amp;gt;&lt;br /&gt;
* Demarrez Felix : &amp;lt;pre&amp;gt;cd felix&lt;br /&gt;
run.bat&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Lancez les commandes du shell Gogo:&lt;br /&gt;
** help&lt;br /&gt;
** lb&lt;br /&gt;
** obr:list&lt;br /&gt;
** obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
** felix:log debug&lt;br /&gt;
** obr:deploy -s &amp;quot;Apache Felix iPOJO&amp;quot;&lt;br /&gt;
** obr:deploy -s &amp;quot;Apache Felix iPOJO Gogo Command&amp;quot;&lt;br /&gt;
** obr:deploy -s &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
** inspect requirement service&lt;br /&gt;
** inspect r service&lt;br /&gt;
** inspect capability service&lt;br /&gt;
** inspect c service &lt;br /&gt;
&lt;br /&gt;
==Cron4j==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
---------------&lt;br /&gt;
Cron4J http://www.sauronsoftware.it/projects/cron4j/ est une bibliotheque java pour dÈclencher pÈriodiquement des taches.&lt;br /&gt;
Elle est inspirée du cron Unix http://fr.wikipedia.org/wiki/Crontab.&lt;br /&gt;
Les taches doivent implémenter l&#039;interface java.lang.Runnable.&lt;br /&gt;
Regardez les exemples fournis dans osgi-part2\cron4j\cron4j-orig\examples&lt;br /&gt;
&lt;br /&gt;
Votre travail est d&#039;utiliser cette bibliotheque pour dÈclencher pÈriodiquement des services OSGi dont l&#039;interface est java.lang.Runnable et la propriÈtÈ cron4j.pattern contient le pattern cron&lt;br /&gt;
Voir le schÈma d&#039;architecture osgi-part2\architecture.ppt&lt;br /&gt;
&lt;br /&gt;
1) Deployez les bundles Cron4J depuis le repository via FileInstall en les dÈposant dans le rÈpertoire .\load de l&#039;installation de Felix&lt;br /&gt;
cron4j-bundle-0.2.0-SNAPSHOT.jar&lt;br /&gt;
cron4j-bundle.example-0.1.0.jar&lt;br /&gt;
&lt;br /&gt;
Que se passe t&#039;il ?&lt;br /&gt;
lb&lt;br /&gt;
inspect c service&lt;br /&gt;
inspect r service&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ipojo:factories&lt;br /&gt;
ipojo:factory&lt;br /&gt;
ipojo:handlers&lt;br /&gt;
ipojo:instance&lt;br /&gt;
ipojo:instances&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) completer le code du projet cron4j-bundle pour qu&#039;il schedule des services java.lang.Runnable&lt;br /&gt;
Moins de 20 lignes de Java&lt;br /&gt;
&lt;br /&gt;
3) ajouter au composant iPOJO un requires http://felix.apache.org/site/service-requirement-handler.html vers un LogService et completer le code du composant pour journaliser les enreisgrements et desenregistrement de services &lt;br /&gt;
(ie utiliser le LogService)&lt;br /&gt;
&lt;br /&gt;
inspect c service&lt;br /&gt;
inspect r service&lt;br /&gt;
&lt;br /&gt;
4) transformez ce Requires en TemporalRequires&lt;br /&gt;
Observez ce qu&#039;il se passe quand le LogService disparait !&lt;br /&gt;
&lt;br /&gt;
inspect c service&lt;br /&gt;
inspect r service&lt;br /&gt;
&lt;br /&gt;
5) Completez le composant iPOJO pour fournir une commande Gogo Shell listant les &amp;quot;schedules&amp;quot; en cours et leurs statitisques (nombre d&#039;invocations, temps restant jusqu&#039;a la prochaine invocation, nombre d&#039;invocation restante, ...)&lt;br /&gt;
Ce complement est livrÈe dans la version cron4j-bundle-0.3.0-SNAPSHOT.jar&lt;br /&gt;
&lt;br /&gt;
inspect c service&lt;br /&gt;
inspect r service&lt;br /&gt;
&lt;br /&gt;
Inspirez vous du code de la commande Arch d&#039;iPOJO (voir le repertoire cron4j-cmd)&lt;br /&gt;
http://svn.apache.org/viewvc/felix/trunk/ipojo/arch-gogo/&lt;br /&gt;
http://svn.apache.org/viewvc/felix/trunk/ipojo/arch-gogo/pom.xml?view=co&lt;br /&gt;
http://svn.apache.org/viewvc/felix/trunk/ipojo/arch-gogo/src/main/java/org/apache/felix/ipojo/arch/gogo/Arch.java?view=co &lt;br /&gt;
http://felix.apache.org/site/rfc-147-overview.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
inspect c service&lt;br /&gt;
inspect r service&lt;br /&gt;
&lt;br /&gt;
----------------&lt;br /&gt;
Extra 1&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix iPOJO White Board Pattern Handler&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix iPOJO Temporal Service Dependency Handler&amp;quot;&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix iPOJO WebConsole Plugins&amp;quot;&lt;br /&gt;
browse http://localhost:8080/system/console/bundles&lt;br /&gt;
Username=admin Password=admin&lt;br /&gt;
&lt;br /&gt;
----------------&lt;br /&gt;
Extra 2&lt;br /&gt;
Ajouter les metadonnÈes du handler JMX au composant TransientCronDeamon&lt;br /&gt;
http://felix.apache.org/site/ipojo-jmx-handler.html&lt;br /&gt;
&lt;br /&gt;
Redeployez le bundle&lt;br /&gt;
Lancez jconsole dans un shell/cmd&lt;br /&gt;
Changez les propriÈtÈs du composant via la JConsole &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Minimal Gogo Command with iPOJO&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Component;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Instantiate;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Provides;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.ServiceProperty;&lt;br /&gt;
import org.apache.felix.service.command.Descriptor;&lt;br /&gt;
&lt;br /&gt;
@Component(immediate = true)&lt;br /&gt;
@Instantiate&lt;br /&gt;
@Provides(specifications = ListComponentsCommand.class)&lt;br /&gt;
public class ListComponentsCommand {&lt;br /&gt;
&lt;br /&gt;
    @ServiceProperty(name = &amp;quot;osgi.command.scope&amp;quot;, value = &amp;quot;test&amp;quot;)&lt;br /&gt;
    String scope;&lt;br /&gt;
&lt;br /&gt;
    @ServiceProperty(name = &amp;quot;osgi.command.function&amp;quot;, value = &amp;quot;{}&amp;quot;)&lt;br /&gt;
    String[] function = new String[] { &amp;quot;test&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
    @Descriptor(&amp;quot;test&amp;quot;)&lt;br /&gt;
    public void test() {&lt;br /&gt;
        System.out.println(&amp;quot;test!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11327</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11327"/>
		<updated>2013-04-19T08:50:44Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* FileInstall */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Préparation pour HTTP Service ==&lt;br /&gt;
&lt;br /&gt;
Plus loin dans le TP, le service HTTP sera installé est devra utiliser un port réseau, par défaut 8080.&lt;br /&gt;
Si ce port est déjà occupé par une autre application (tester avec un navigateur: http://localhost:8080/), il faut modifier le fichier &amp;lt;pre&amp;gt;conf/config.properties&amp;lt;/pre&amp;gt; dans le dossier &amp;lt;pre&amp;gt;%FELIX_HOME%&amp;lt;/pre&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
À la fin du fichier, remplacer la ligne&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=8080&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
par&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=&amp;lt;numéro de port&amp;gt;&lt;br /&gt;
org.apache.felix.http.jettyEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&lt;br /&gt;
Si le proxy campus est actif:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar bin/felix.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
(peux échouer)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont été déployés (installés et démarrés) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du répertoire .\repository vers .\load depuis un terminal&lt;br /&gt;
&lt;br /&gt;
Sous Windows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sous Linux:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
copy ./repository/org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar ./load&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que s&#039;est il passé ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
Supprimez le JAR file.&lt;br /&gt;
&lt;br /&gt;
Sous Windows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sous Linux:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rm ./load/org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Que s&#039;est il passé ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11326</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11326"/>
		<updated>2013-04-19T08:35:03Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Deploiement de bundles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Préparation pour HTTP Service ==&lt;br /&gt;
&lt;br /&gt;
Plus loin dans le TP, le service HTTP sera installé est devra utiliser un port réseau, par défaut 8080.&lt;br /&gt;
Si ce port est déjà occupé par une autre application (tester avec un navigateur: http://localhost:8080/), il faut modifier le fichier &amp;lt;pre&amp;gt;conf/config.properties&amp;lt;/pre&amp;gt; dans le dossier &amp;lt;pre&amp;gt;%FELIX_HOME%&amp;lt;/pre&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
À la fin du fichier, remplacer la ligne&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=8080&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
par&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=&amp;lt;numéro de port&amp;gt;&lt;br /&gt;
org.apache.felix.http.jettyEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&lt;br /&gt;
Si le proxy campus est actif:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar bin/felix.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
(peux échouer)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont été déployés (installés et démarrés) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11325</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11325"/>
		<updated>2013-04-19T08:30:35Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Deployez et lancez la Web console via l&amp;#039;OBR */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Préparation pour HTTP Service ==&lt;br /&gt;
&lt;br /&gt;
Plus loin dans le TP, le service HTTP sera installé est devra utiliser un port réseau, par défaut 8080.&lt;br /&gt;
Si ce port est déjà occupé par une autre application (tester avec un navigateur: http://localhost:8080/), il faut modifier le fichier &amp;lt;pre&amp;gt;conf/config.properties&amp;lt;/pre&amp;gt; dans le dossier &amp;lt;pre&amp;gt;%FELIX_HOME%&amp;lt;/pre&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
À la fin du fichier, remplacer la ligne&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=8080&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
par&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=&amp;lt;numéro de port&amp;gt;&lt;br /&gt;
org.apache.felix.http.jettyEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&lt;br /&gt;
Si le proxy campus est actif:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar bin/felix.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
(peux échouer)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont été déployés (installés et démarrés) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11324</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11324"/>
		<updated>2013-04-19T08:25:59Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Installation et configuration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Préparation pour HTTP Service ==&lt;br /&gt;
&lt;br /&gt;
Plus loin dans le TP, le service HTTP sera installé est devra utiliser un port réseau, par défaut 8080.&lt;br /&gt;
Si ce port est déjà occupé par une autre application (tester avec un navigateur: http://localhost:8080/), il faut modifier le fichier &amp;lt;pre&amp;gt;conf/config.properties&amp;lt;/pre&amp;gt; dans le dossier &amp;lt;pre&amp;gt;%FELIX_HOME%&amp;lt;/pre&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
À la fin du fichier, remplacer la ligne&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=8080&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
par&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
org.osgi.service.http.port=&amp;lt;numéro de port&amp;gt;&lt;br /&gt;
org.apache.felix.http.jettyEnabled=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&lt;br /&gt;
Si le proxy campus est actif:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar bin/felix.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
(peux échouer)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont été déployés (installés et démarrés) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11323</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11323"/>
		<updated>2013-04-19T08:15:12Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Deployez et lancez la Web console via l&amp;#039;OBR */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&lt;br /&gt;
Si le proxy campus est actif:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar bin/felix.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;org.apache.felix.webconsole&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
(peux échouer)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont été déployés (installés et démarrés) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11322</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11322"/>
		<updated>2013-04-19T07:51:15Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Lancement de Felix */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&lt;br /&gt;
Si le proxy campus est actif:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sinon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar bin/felix.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot; &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont ÈtÈ dÈployÈs (installÈs et dÈmarrÈs) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11321</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11321"/>
		<updated>2013-04-19T07:50:29Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* PremiËres commandes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Premières commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot; &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont ÈtÈ dÈployÈs (installÈs et dÈmarrÈs) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11320</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11320"/>
		<updated>2013-04-19T07:49:13Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* PremiËres commandes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PremiËres commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot; &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont ÈtÈ dÈployÈs (installÈs et dÈmarrÈs) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11319</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11319"/>
		<updated>2013-04-19T07:48:56Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Changement du niveau d&amp;#039;execution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PremiËres commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log debug&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log debug&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot; &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont ÈtÈ dÈployÈs (installÈs et dÈmarrÈs) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11318</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 1</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_1&amp;diff=11318"/>
		<updated>2013-04-19T07:48:34Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Deploiement de bundles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Installation et configuration=&lt;br /&gt;
Telechargez la derniËre distribution de Felix depuis&lt;br /&gt;
http://felix.apache.org/site/downloads.cgi&lt;br /&gt;
&lt;br /&gt;
DÈzippez la distribution dans le repertoire du TP&lt;br /&gt;
&lt;br /&gt;
Configurez les variables JAVA_HOME et PATH&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set FELIX_VER=4.0.2&lt;br /&gt;
set FELIX_HOME=felix-framework-%FELIX_VER%&lt;br /&gt;
set JAVA_HOME=c:\Progra~1\Java\jre6&lt;br /&gt;
set PATH=%JAVA_HOME%\bin;%PATH%&lt;br /&gt;
java -version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
creez les repertoires dans %FELIX_HOME%&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir %FELIX_HOME%\load&lt;br /&gt;
mkdir %FELIX_HOME%\repository&lt;br /&gt;
&lt;br /&gt;
copy repository\*.* %FELIX_HOME%\repository&lt;br /&gt;
copy run.bat %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
le fichier run.bat permet de lancer Felix avec le proxy HTTP configurÈ avec celui de l&#039;UJF (www-cache.ujf-grenoble.fr:3128)&lt;br /&gt;
&lt;br /&gt;
Positionnez &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd %FELIX_HOME%&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lancement de Felix=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
run.bat&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=PremiËres commandes=&lt;br /&gt;
Depuis le shell Gogo de Felix&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
help&lt;br /&gt;
lb&lt;br /&gt;
headers&lt;br /&gt;
inspect capability osgi.wiring.package 0&lt;br /&gt;
inspect requirement osgi.wiring.package 0&lt;br /&gt;
inspect capability service 0&lt;br /&gt;
inspect requirement service 0&lt;br /&gt;
&lt;br /&gt;
inspect c osgi.wiring.package 1&lt;br /&gt;
inspect r osgi.wiring.package 1&lt;br /&gt;
inspect c service 1&lt;br /&gt;
inspect r service 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix Log Service&amp;quot;&lt;br /&gt;
help log&lt;br /&gt;
log debug&lt;br /&gt;
log info&lt;br /&gt;
log warn&lt;br /&gt;
log error&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Deploiement de bundles=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
install file:./repository/org.apache.felix.sandbox.mbean.shell.felix.gogo-0.4.0.jar&lt;br /&gt;
lb&lt;br /&gt;
start 5&lt;br /&gt;
inspect c osgi.wiring.package 5&lt;br /&gt;
inspect r osgi.wiring.package 5&lt;br /&gt;
inspect c service 5&lt;br /&gt;
inspect r service 5&lt;br /&gt;
&lt;br /&gt;
update 5&lt;br /&gt;
log debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
install http://repo1.maven.org/maven2/org/apache/felix/org.apache.felix.http.jetty/1.0.1/org.apache.felix.http.jetty-1.0.1.jar&lt;br /&gt;
log 1&lt;br /&gt;
lb&lt;br /&gt;
start 6&lt;br /&gt;
uninstall 6&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que se passe t&#039;il et pourquoi ?&lt;br /&gt;
&lt;br /&gt;
=Changement du niveau d&#039;execution=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
lb&lt;br /&gt;
help bundlelevel&lt;br /&gt;
bundlelevel &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
frameworklevel&lt;br /&gt;
bundlelevel -s 2 &amp;lt;OBR&#039; bundle Id&amp;gt;&lt;br /&gt;
log&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frameworklevel 2&lt;br /&gt;
log&lt;br /&gt;
lb&lt;br /&gt;
obr:list&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
que s&#039;est il passÈ ?&lt;br /&gt;
&lt;br /&gt;
=Deployez et lancez la Web console via l&#039;OBR=&lt;br /&gt;
Qu&#039;est que l&#039;OBR ([[OSGi Bundle Repository]]) ?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:help&lt;br /&gt;
obr:list&lt;br /&gt;
obr:info &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&lt;br /&gt;
obr:deploy -s &amp;quot;Apache Felix Web Management Console&amp;quot; &amp;quot;Apache Felix Web Console Event Plugin&amp;quot; &amp;quot;Apache Felix Web Console Memory Usage Plugin&amp;quot; &amp;quot;Apache Felix Web Console Service Diagnostics Plugin&amp;quot; &amp;quot;Apache Felix Web Console UPnP Plugin&amp;quot;&lt;br /&gt;
lb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Combien de bundles ont ÈtÈ dÈployÈs (installÈs et dÈmarrÈs) ?&lt;br /&gt;
&lt;br /&gt;
naviguez http://localhost:8080/system/console depuis votre browser (username et password : admin et admin)&lt;br /&gt;
&lt;br /&gt;
Deployez File Install soit depuis la web console onglet &amp;quot;OSGi repository&amp;quot;&lt;br /&gt;
soit avec la commande&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
obr:deploy -start &amp;quot;Apache Felix File Install&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=FileInstall=&lt;br /&gt;
Deployez des bundles via FileInstall en copiant les jarfiles des bundles du rÈpertoires .\repertoire vers .\load depuis un cmd DOS&lt;br /&gt;
copy .\repository\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar .\load&lt;br /&gt;
Que s&#039;est il passÈ ? (faire lb puis log 4)&lt;br /&gt;
&lt;br /&gt;
del .\load\org.apache.felix.examples.managedservice-0.1.0-SNAPSHOT.jar&lt;br /&gt;
Que s&#039;est il passÈ ?  (faire lb puis log 4)&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Arduino&amp;diff=9421</id>
		<title>Arduino</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Arduino&amp;diff=9421"/>
		<updated>2013-03-06T13:35:07Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* Liens */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:arduinos.jpg|200px|thumb|Assortiments d&#039;Arduino et consors: Uno, Mega, Seeeduino, FEZ Panda]]&lt;br /&gt;
[[Image:arduinoteam.jpg|200px|thumb|The Arduino (Dream) Team]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Description==&lt;br /&gt;
Arduino est un ensemble de cartes à base d&#039;AVR ATMega pour le prototypage rapide d&#039;applications &#039;&#039;[[physical computing]]&#039;&#039; mêlant programmation simple et électronique de base. Elle s&#039;adresse aux artistes, hobbiistes, lycéens et enseignants.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Les points forts de cette carte sont:&lt;br /&gt;
* son caractère [[open-source]] (multi fournisseurs, ...)&lt;br /&gt;
* son environnement simplifié pour le développement (basé sur [[Processing]], langage Wiring, programmation vers l&#039;USB, ...)&lt;br /&gt;
* sa communauté d&#039;utilisateurs (millions, entraide, idées de projet, ...)&lt;br /&gt;
* sa connection avec l&#039;environnement [[Processing]] (sur un hôte PC, Mac, ...)&lt;br /&gt;
&lt;br /&gt;
Les points faible de cette carte sont:&lt;br /&gt;
* des capacités limitées en mémoire RAM et FLASH&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
===Windows===&lt;br /&gt;
Téléchargez l&#039;environnement de développement Arduino depuis http://www.arduino.cc/en/Main/Software&lt;br /&gt;
&lt;br /&gt;
Dézippez l&#039;environnement (qui requière un JRE)&lt;br /&gt;
&lt;br /&gt;
Installez les drivers de votre carte (Uno, Duemilanove ...) présents dans le répertoire arduino-0xyz\drivers en suivant les [http://arduino.cc/en/Guide/Windows#toc4 instructions].&lt;br /&gt;
&lt;br /&gt;
===MacOS X===&lt;br /&gt;
&lt;br /&gt;
===Linux===&lt;br /&gt;
Sous Linux [http://www.arduino.cc/playground/Learning/Linux http://www.arduino.cc/playground/Learning/Linux]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt-get install arduino&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More for Ubuntu at &#039;&#039;http://arduino.cc/playground/Linux/Ubuntu&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Quote:&lt;br /&gt;
&#039;&#039;Is there any way I can &amp;quot;see&amp;quot; the avrdude command the Arduino IDE uses (since it works)?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Close the IDE if running and open the preferences.txt file for the IDE in a texteditor. Change  the keys :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
build.verbose=true&lt;br /&gt;
upload.verbose=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then startup the IDE.  It should now print all the compiler and avrdude upload messages.&lt;br /&gt;
&lt;br /&gt;
Related info&lt;br /&gt;
&lt;br /&gt;
* For Arduino 22 on 64 bit [http://thenybble.de/projects/arduino-64-bit.html http://thenybble.de/projects/arduino-64-bit.html]&lt;br /&gt;
* Ecplise plugin [http://www.arduino.cc/playground/Code/Eclipse http://www.arduino.cc/playground/Code/Eclipse]&lt;br /&gt;
&lt;br /&gt;
==Premiers pas==&lt;br /&gt;
Pour tester que l&#039;installation est opérationnelle:&lt;br /&gt;
* connectez votre carte Arduino sur le port USB de votre machine&lt;br /&gt;
* lancez l&#039;environnement Arduino&lt;br /&gt;
* sélectionnez le modèle de votre carte Arduino : &#039;&#039;Menu Tools &amp;gt; Board&#039;&#039;&lt;br /&gt;
* sélectionnez le port série (ie port COM sous Windows) sur lequel se trouve brancher votre carte Arduino : &#039;&#039;Menu Tools &amp;gt; Serial Port&#039;&#039; &lt;br /&gt;
* ouvrez l&#039;exemple Blink &#039;&#039;Menu File &amp;gt; Examples &amp;gt; 1.Basics &amp;gt; Blink&#039;&#039;&lt;br /&gt;
* compilez et chargez le code sur la carte &#039;&#039;Menu File &amp;gt; Upload to IO Board&#039;&#039;&lt;br /&gt;
* normalement, la LED 13 de la carte clignote en continu ! (dès qu&#039;elle est alimentée, la carte boot et exécute ce programme qui est installé dans la FlashRAM.&lt;br /&gt;
&lt;br /&gt;
C&#039;est tout bon : à vous de jouer ...&lt;br /&gt;
&lt;br /&gt;
Vous pouvez tester les autres exemples &#039;&#039;Menu File &amp;gt; Examples&#039;&#039;&lt;br /&gt;
Notamment celui utilisant le port série &#039;&#039;Menu File &amp;gt; Examples &amp;gt; 4.Communication &amp;gt; ASCIITable&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Voici un aide mémoire Arduino [[Media:arduinocheatsheet.pdf]] ([http://sites.google.com/site/mechatronicsguy/arduinocheatsheet/Arduinocheatsheetv02c.pdf?attredirects=0&amp;amp;d=1 original])&lt;br /&gt;
&lt;br /&gt;
et d&#039;autres manipulations avec des capteurs et des actionneurs&lt;br /&gt;
* Sparkfun Inventor Kit (en VO)&lt;br /&gt;
** http://www.sparkfun.com/tutorial/AIK/ARDX-EG-SPAR-PRINT-85.pdf&lt;br /&gt;
** http://www.sparkfun.com/tutorial/AIK/CIRC00-sheet-SPAR.pdf&lt;br /&gt;
* Sparkfun Inventor Kit (en VF)&lt;br /&gt;
** http://ardx.org/src/guide/2/ARDX-EG-SPAR-FR-WEB.pdf&lt;br /&gt;
** http://www.sparkfun.com/news/636&lt;br /&gt;
&lt;br /&gt;
Des [[Travaux Pratiques Arduino]] plus conséquents sont disponibles pour les élèves de AIR.&lt;br /&gt;
&lt;br /&gt;
==Avancés==&lt;br /&gt;
[http://robotgroup.com.ar/duinos/wiki/index.php?title=Main_Page-FR DuinOS] un OS temps réel pour Arduino.&lt;br /&gt;
&lt;br /&gt;
==Arduino @ AIR==&lt;br /&gt;
Les cartes disponibles dans la salle AIR:&lt;br /&gt;
* [http://arduino.cc/en/Main/ArduinoBoardUno Arduino Uno]&lt;br /&gt;
* Arduino Duemilanove&lt;br /&gt;
* [http://arduino.cc/en/Main/ArduinoBoardMega2560 Arduino Mega2560]&lt;br /&gt;
* [http://www.arduino.cc/en/Main/ArduinoBoardLilyPad Arduino Lilypad]&lt;br /&gt;
* [[Arduino FIO]] (included XBee socket)&lt;br /&gt;
* [http://www.seeedstudio.com/depot/seeeduino-stalker-p-600.html Seeeduino Stalker] (included ZigBee + SD Card)&lt;br /&gt;
* &amp;quot;[[Breaduino]]&amp;quot; (Arduino bootable ATMega328 standalone)&lt;br /&gt;
&lt;br /&gt;
Des cartes &#039;&#039;erzats&#039;&#039; utilisant des processeurs ARM7 sont compatibles avec les montages et les cartes filles développées pour les cartes Arduino. Pour certaines, le développement se fait par contre en C# .NET MicroFramework&lt;br /&gt;
* [[Arduino Due]]&lt;br /&gt;
* [[chipKIT Uno32]]&lt;br /&gt;
* [[Netduino]]&lt;br /&gt;
* [[FEZ]] Panda&lt;br /&gt;
&lt;br /&gt;
Des cartes [[FPGA]] comme la carte [[Papilio]] peuvent être synthètisées en AVR8 (ou [[ZPUino|ZPU]]) et exécuter des schetches Arduino via l&#039;IDE Arduino modifié.&lt;br /&gt;
 &lt;br /&gt;
[[Image:arduinos.jpg|500px|Assortiments d&#039;Arduino et consors: Uno, Mega, Seeeduino, FEZ Panda]][[Image:arduigrid-v0.1.jpg|500px|ArduiGrid]][[Image:Breaduino1.jpg|300px|Breaduino]][[Image:Solarpanel2.jpg|300px|Module XBee sur Arduino Fio]][[Image:papilio500Arcade2.jpg|300px|Carte FPGA Papilio 500K + Papilio Arcade MegaWing + Vintage joysticks (6 switches)]]&lt;br /&gt;
&lt;br /&gt;
==Ressources==&lt;br /&gt;
===Liens===&lt;br /&gt;
* [http://www.arduino.cc Arduino Website]&lt;br /&gt;
* [http://www.arduino.cc/en/Main/Hardware Arduino Hardware]&lt;br /&gt;
* [http://membres-liglab.imag.fr/donsez/cours/arduino.pdf Transparents du cours]&lt;br /&gt;
* Un trés bon [http://fr.flossmanuals.net/arduino/ flossmanuals] sur l&#039;arduino&lt;br /&gt;
* Un aide mémoire sur Arduino [[Media:arduinocheatsheet.pdf]] ([http://sites.google.com/site/mechatronicsguy/arduinocheatsheet/Arduinocheatsheetv02c.pdf?attredirects=0&amp;amp;d=1 original])&lt;br /&gt;
* &#039;&#039;[http://gitorious.org/simavr simavr] is a new AVR simulator for linux, or any platform that uses avr-gcc. It uses avr-gcc own register definition to simplify creating new targets for supported AVR devices&#039;&#039;&lt;br /&gt;
* [[Modk.it]]&lt;br /&gt;
* http://blog.ardublock.com/&lt;br /&gt;
* [http://android.serverbox.ch/?p=549 Arduino avec Android (USB Host)]&lt;br /&gt;
&lt;br /&gt;
===Kits===&lt;br /&gt;
* Sparkfun Inventor Kit (un kit de base pour démarrer avec l&#039;Ardiuno en VO&lt;br /&gt;
** http://www.sparkfun.com/tutorial/AIK/ARDX-EG-SPAR-PRINT-85.pdf&lt;br /&gt;
** http://www.sparkfun.com/tutorial/AIK/CIRC00-sheet-SPAR.pdf&lt;br /&gt;
* Sparkfun Inventor Kit (en VF)&lt;br /&gt;
** http://ardx.org/src/guide/2/ARDX-EG-SPAR-FR-WEB.pdf&lt;br /&gt;
** http://www.sparkfun.com/news/636&lt;br /&gt;
&lt;br /&gt;
===Livres===&lt;br /&gt;
* Massimo Banzi, Getting Started with Arduino, Pub. Make; 1 edition (October 15, 2008) ISBN-10: 0596155514&lt;br /&gt;
* Tom Igoe, [http://oreilly.com/catalog/9780596510510 Making Things Talk: Practical Methods for Connecting Physical Objects],  Make; 1 edition (September 28, 2007), ISBN-10: 0596510519 ([http://examples.oreilly.com/9780596510510/ exemples de code]) un livre plein de recette de cuisine !&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_4&amp;diff=7103</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 4</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_4&amp;diff=7103"/>
		<updated>2012-12-20T10:17:47Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* II. Pure-OSGi service */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&lt;br /&gt;
* Felix Framework Distribution (voir [[Tutorial OSGi avec Apache Felix - Partie 1]])&lt;br /&gt;
** with the iPOJO Core bundle[http://felix.apache.org/site/download.html] (see next section)&lt;br /&gt;
* [http://www.eclipse.org/downloads/ Eclipse].&lt;br /&gt;
** To support OSGi development, Eclipse needs the &#039;&#039;&#039;PDE&#039;&#039;&#039; (Plug-in Development Environment) plug-in, bundled in &#039;&#039;Eclipse IDE for Java EE Developers&#039;&#039;&lt;br /&gt;
* iPOJO Nature plug-in for Eclipse, available [https://dl.dropbox.com/u/59622687/org.ow2.chameleon.eclipse.ipojo.updatesite-1.0.1-SNAPSHOT.zip as an archive distribution]&lt;br /&gt;
** Install the &#039;&#039;iPOJO Project Nature&#039;&#039; and &#039;&#039;iPOJO Nature Dependencies&#039;&#039; plug-ins&lt;br /&gt;
&lt;br /&gt;
==Set up your Felix installation==&lt;br /&gt;
&lt;br /&gt;
# Run Felix using the following command in the Felix installation directory&lt;br /&gt;
#* &amp;lt;code&amp;gt;java -jar bin/felix.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
# Install iPOJO, using the following Felix Gogo shell commands:&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:list&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix iPOJO&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix iPOJO Gogo Command&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Useful Gogo commands==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note&#039;&#039;: To ease shell lines edition on Linux, you might use the [http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap rlwrap] tool: &amp;lt;code&amp;gt;rlwrap java -jar bin/felix.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;help {command}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Print the help of the given command&lt;br /&gt;
* &amp;lt;code&amp;gt;lb&amp;lt;/code&amp;gt;&lt;br /&gt;
** Lists the bundles installed in the framework&lt;br /&gt;
* &amp;lt;code&amp;gt;inspect capability service {bundle ID}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Lists the services provided by the given bundle&lt;br /&gt;
** &amp;lt;code&amp;gt;capability&amp;lt;/code&amp;gt; can be written &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;inspect requirement service {bundle ID}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Lists the services consumed by the given bundle&lt;br /&gt;
** &amp;lt;code&amp;gt;requirement&amp;lt;/code&amp;gt; can be written &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:factories&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the publicly available iPOJO factories&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:factory {factory name}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the details of the given iPOJO factory&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:instances&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the names and states of iPOJO instances&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:instance {instance name}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the details of the given iPOJO component instance&lt;br /&gt;
&lt;br /&gt;
==Eclipse Configuration==&lt;br /&gt;
&lt;br /&gt;
By default, Eclipse uses its installation directory as the Target Platform, i.e. the group of bundles accessible by your bundle project.&lt;br /&gt;
You should declare the installation folder of the Felix Framework as the target platform to avoid compilation and access rights errors.&lt;br /&gt;
&lt;br /&gt;
# Open Eclipse preferences&lt;br /&gt;
# Plug-in Development &amp;gt; Target Platform&lt;br /&gt;
# Add...&lt;br /&gt;
## Create an empty target platform (check &#039;&#039;nothing...&#039;&#039;)&lt;br /&gt;
## Add the &#039;&#039;bin&#039;&#039; and &#039;&#039;bundle&#039;&#039; folders of your Felix installation to the Target Platform&lt;br /&gt;
# Set the new target platform as the current one&lt;br /&gt;
&lt;br /&gt;
=I. Activator=&lt;br /&gt;
&lt;br /&gt;
# Create an Eclipse Plug-in project &#039;&#039;fr.erods.tp.bundle1&#039;&#039;&lt;br /&gt;
#* New &amp;gt; Plug-in project&lt;br /&gt;
#* Select the option &amp;quot;Target Platform&amp;quot; &amp;gt; &amp;quot;an OSGi framework&amp;quot; &amp;gt; &#039;&#039;standard&#039;&#039;&lt;br /&gt;
#* Next&lt;br /&gt;
#* Check &amp;quot;Generate an activator&amp;quot;&lt;br /&gt;
#* Finish&lt;br /&gt;
# Open the activator class and print some text when the bundle starts and stops&lt;br /&gt;
# Export the bundle JAR file with iPOJO Nature&lt;br /&gt;
#* Right click on the bundle project &amp;gt; Export &amp;gt; iPOJO Bundle&lt;br /&gt;
#* Choose an output folder (the Felix installation folder)&lt;br /&gt;
#* Finish&lt;br /&gt;
# Install and test the bundle using the Felix shell (start/update/stop)&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* Indicate when start() and stop() methods are called.&lt;br /&gt;
* Why the BundleContext can be kept as a &amp;lt;code&amp;gt;private static&amp;lt;/code&amp;gt; class member ?&lt;br /&gt;
&lt;br /&gt;
=II. Pure-OSGi service=&lt;br /&gt;
&lt;br /&gt;
# Create an new bundle project &#039;&#039;fr.erods.tp.api&#039;&#039;.&lt;br /&gt;
#* Activator is not needed: uncheck &amp;quot;Generate an activator&amp;quot; in step 2&lt;br /&gt;
# Create the &amp;lt;code&amp;gt;fr.erods.tp.api.IScheduleService&amp;lt;/code&amp;gt; interface with two methods:&lt;br /&gt;
#* &amp;lt;code&amp;gt;int createJob(Runnable aRunnable, int aDelay)&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;void deleteJob(int aId)&amp;lt;/code&amp;gt;&lt;br /&gt;
# Export the API package&lt;br /&gt;
#* Open the Manifest.mf file of &#039;&#039;fr.erods.tp.api&#039;&#039;&lt;br /&gt;
#* In tab &amp;quot;Runtime&amp;quot; &amp;gt; &amp;quot;Exported Packages&amp;quot; &amp;gt; Add&lt;br /&gt;
#** Select the &amp;lt;code&amp;gt;fr.erods.tp.api&amp;lt;/code&amp;gt; package&lt;br /&gt;
# Import the API package in bundle 1&lt;br /&gt;
#* Open the Manifest.mf file of &#039;&#039;fr.erods.tp.bundle1&#039;&#039;&lt;br /&gt;
#* In tab &amp;quot;Dependencies&amp;quot; &amp;gt; &amp;quot;Imported Packages&amp;quot; &amp;gt; Add&lt;br /&gt;
#* Select the &amp;lt;code&amp;gt;fr.erods.tp.api&amp;lt;/code&amp;gt; package&lt;br /&gt;
# Implement the service in bundle 1&lt;br /&gt;
#* Create the class &amp;lt;code&amp;gt;fr.erods.tp.bundle1.ScheduleImpl&amp;lt;/code&amp;gt;, implementing &amp;lt;code&amp;gt;IScheduleService&amp;lt;/code&amp;gt; in the bundle 1.&lt;br /&gt;
# Register the service with the activator of bundle 1&lt;br /&gt;
#* see [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#registerService%28java.lang.Class,%20S,%20java.util.Dictionary%29 registerService()]&lt;br /&gt;
#* see [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/ServiceRegistration.html#unregister%28%29 unregister()]&lt;br /&gt;
# Implement a service consumer in a new bundle&lt;br /&gt;
#* Create project &#039;&#039;fr.erods.tp.bundle2&#039;&#039;&lt;br /&gt;
#* Import the API package&lt;br /&gt;
#** In the Manifest.mf file of bundle 2&lt;br /&gt;
#** In tab &amp;quot;Dependencies&amp;quot; &amp;gt; &amp;quot;Imported Packages&amp;quot; &amp;gt; Add&lt;br /&gt;
#** Select the &amp;lt;code&amp;gt;fr.erods.tp.api&amp;lt;/code&amp;gt; package&lt;br /&gt;
#* Implement a &amp;lt;code&amp;gt;Consumer&amp;lt;/code&amp;gt; class, implementing the OSGi &amp;lt;code&amp;gt;ServiceListener&amp;lt;/code&amp;gt;[http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/ServiceListener.html] interface&lt;br /&gt;
#* Print a message when the service is bound/unbound&lt;br /&gt;
# Test the bundles in Felix&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* What happens when the consumer is started after the service bundle and why ?&lt;br /&gt;
* Correct this behavior, using [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#getServiceReference%28java.lang.Class%29 getServiceReference()] and [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#getService%28org.osgi.framework.ServiceReference%29 getService()]&lt;br /&gt;
&lt;br /&gt;
=II. iPOJO: provide and consume with iPOJO=&lt;br /&gt;
&lt;br /&gt;
# Add the iPOJO Nature to projects &#039;&#039;bundle 1&#039;&#039; and &#039;&#039;bundle 2&#039;&#039;&lt;br /&gt;
#* Select the projects&lt;br /&gt;
#* Right click &amp;gt; Add iPOJO Nature&lt;br /&gt;
#* Check &#039;&#039;Use annotations&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Consumer==&lt;br /&gt;
&lt;br /&gt;
# Implement a &amp;lt;code&amp;gt;ConsumerIpojo&amp;lt;/code&amp;gt; class in bundle 2&lt;br /&gt;
#* See [http://felix.apache.org/site/how-to-use-ipojo-annotations.html How to use iPOJO Annotations]&lt;br /&gt;
#* The component must be instantiated automatically&lt;br /&gt;
#* Print a message when the component is (in)validated and when the service is (un)bound&lt;br /&gt;
# Test&lt;br /&gt;
# Set the service requirement as optional&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* Why are the callbacks called in that order ?&lt;br /&gt;
* What happens if you use a missing optional requirement ?&lt;br /&gt;
&lt;br /&gt;
==Provider==&lt;br /&gt;
&lt;br /&gt;
# Implement a &amp;lt;code&amp;gt;ServiceProviderIpojo&amp;lt;/code&amp;gt; class in bundle 1&lt;br /&gt;
#* See [http://felix.apache.org/site/how-to-use-ipojo-annotations.html How to use iPOJO Annotations]&lt;br /&gt;
#* The component must be instantiated automatically&lt;br /&gt;
#* The component must provide its service&lt;br /&gt;
#* Print a message when the component is (in)validated&lt;br /&gt;
# Test&lt;br /&gt;
# Add a &#039;&#039;service controller&#039;&#039; and alternate the service presence&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
Question:&lt;br /&gt;
* How does the consumers react to the service presence cycle ?&lt;br /&gt;
&lt;br /&gt;
==Bonus==&lt;br /&gt;
&lt;br /&gt;
# Add a &amp;quot;service.ranking&amp;quot; property to the pure-OSGi and the iPOJO service, and an &amp;quot;implementation&amp;quot; property to identify them&lt;br /&gt;
# Print the name of the implementation the consumers are bound to&lt;br /&gt;
# Modify the ranking value&lt;br /&gt;
&lt;br /&gt;
Question:&lt;br /&gt;
* How does a service the service selection works ?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note&#039;&#039;: The consumer should call methods of the service and traces should be printed in order to show which service the consumer is bound to.&lt;br /&gt;
&lt;br /&gt;
=III. Whiteboard pattern=&lt;br /&gt;
&lt;br /&gt;
# Create interface &amp;lt;code&amp;gt;IJobListener&amp;lt;/code&amp;gt; in the API package, with two methods:&lt;br /&gt;
#* &amp;lt;code&amp;gt;void onJobCreation(int aId)&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;void onJobDeletion(int aId)&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create a new bundle project &#039;&#039;fr.erods.tp.bundle3&#039;&#039;&lt;br /&gt;
#* Add the iPOJO Nature and annotations&lt;br /&gt;
#* Let it import the API package&lt;br /&gt;
# Create a component providing an &amp;lt;code&amp;gt;IJobListener&amp;lt;/code&amp;gt; service in bundle 3&lt;br /&gt;
# Add job creation / deletion operations in a consumer&lt;br /&gt;
&lt;br /&gt;
==Subscription pattern==&lt;br /&gt;
&lt;br /&gt;
# Modify the schedule component to allow listeners registration:&lt;br /&gt;
#* &amp;lt;code&amp;gt;void addListener(IJobListener)&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;void removeListener(IJobListener)&amp;lt;/code&amp;gt;&lt;br /&gt;
# Register component of bundle 3 as a job listener&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
==Whiteboard pattern==&lt;br /&gt;
&lt;br /&gt;
# Modify the schedule component (in bundle 1)&lt;br /&gt;
#* Remove the registration methods created above&lt;br /&gt;
#* Add a requirement to an array of &amp;lt;code&amp;gt;IJobListener&amp;lt;/code&amp;gt;s, as an optional requirement&lt;br /&gt;
#* Notify them on job creation/deletion&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* What are the pros/cons of the whiteboard pattern vs. the subscription pattern ?&lt;br /&gt;
* Bonus: compare this whiteboard pattern implementation with the iPOJO Whiteboard pattern handler[http://felix.apache.org/site/white-board-pattern-handler.html]&lt;br /&gt;
&lt;br /&gt;
=IV. JMX MBean with iPOJO=&lt;br /&gt;
&lt;br /&gt;
# Create a new bundle, with iPOJO Nature and annotations&lt;br /&gt;
# Create a component, which doesn&#039;t provide any service, but contains public methods to create/delete/list &amp;lt;code&amp;gt;IScheduleService&amp;lt;/code&amp;gt; jobs&lt;br /&gt;
# Use iPOJO JMX annotations[http://felix.apache.org/site/how-to-use-ipojo-annotations.html#HowtouseiPOJOAnnotations-ExposinginstancesasaJMXMBean%28externalhandler%29] to export those methods&lt;br /&gt;
# You will need the iPOJO JMX handler to test this component: install it using the following command in the Felix shell:&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix iPOJO JMX Handler&amp;lt;/code&amp;gt;&lt;br /&gt;
# Install the bundle in the Felix framework&lt;br /&gt;
# Run &amp;lt;code&amp;gt;jconsole&amp;lt;/code&amp;gt; (in the Oracle Java distribution) or &amp;lt;code&amp;gt;jvisualvm&amp;lt;/code&amp;gt; (in the Oracle Java distribution) or &amp;lt;code&amp;gt;visualvm&amp;lt;/code&amp;gt;[http://visualvm.java.net/download.html]&lt;br /&gt;
#* You might need to install the JMX plug-in in VisualVM:&lt;br /&gt;
#** Tools &amp;gt; Plugins &amp;gt; Available Plugi-ns&lt;br /&gt;
#** Install the &#039;&#039;VisualVM-MBeans&#039;&#039; plug-in&lt;br /&gt;
# Connect VisualVM to your Felix JVM and play with the JMX beans&lt;br /&gt;
&lt;br /&gt;
=V. Gogo Command with iPOJO=&lt;br /&gt;
&lt;br /&gt;
# Create a new bundle, with iPOJO Nature and annotations&lt;br /&gt;
# Create a Gogo command provider to create and delete jobs, and to list current jobs status&lt;br /&gt;
&lt;br /&gt;
==Minimal Gogo command component==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Component;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Instantiate;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Provides;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.ServiceProperty;&lt;br /&gt;
import org.apache.felix.service.command.Descriptor;&lt;br /&gt;
&lt;br /&gt;
@Component(immediate = true)&lt;br /&gt;
// Provide the component class as a service&lt;br /&gt;
@Provides(specifications = ListComponentsCommand.class)&lt;br /&gt;
// Instantiate the component automatically&lt;br /&gt;
@Instantiate&lt;br /&gt;
public class ListComponentsCommand {&lt;br /&gt;
&lt;br /&gt;
    // Gogo scope/namespace&lt;br /&gt;
    @ServiceProperty(name = &amp;quot;osgi.command.scope&amp;quot;, value = &amp;quot;test&amp;quot;)&lt;br /&gt;
    String scope;&lt;br /&gt;
&lt;br /&gt;
    // Gogo commands provided by this class (must be methods names)&lt;br /&gt;
    @ServiceProperty(name = &amp;quot;osgi.command.function&amp;quot;, value = &amp;quot;{}&amp;quot;)&lt;br /&gt;
    String[] function = new String[] { &amp;quot;test&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
    // Method description&lt;br /&gt;
    @Descriptor(&amp;quot;test&amp;quot;)&lt;br /&gt;
    public void test() {&lt;br /&gt;
        System.out.println(&amp;quot;test!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=VI. Config Admin with iPOJO=&lt;br /&gt;
&lt;br /&gt;
See [http://felix.apache.org/site/combining-ipojo-and-configuration-admin.html Combining iPOJO and Configuration Admin]&lt;br /&gt;
&lt;br /&gt;
=VII. Event Admin with iPOJO=&lt;br /&gt;
1. Create a new bundle, with iPOJO annotations to send events on jobs status changes&lt;br /&gt;
&lt;br /&gt;
=VIII. Extender with iPOJO=&lt;br /&gt;
??&lt;br /&gt;
&lt;br /&gt;
=Guidelines &amp;amp; Good Practices (&amp;quot;OSGi Zen&amp;quot;)=&lt;br /&gt;
&lt;br /&gt;
* Always separate API and implementations&lt;br /&gt;
* Always release services and resources once you&#039;re done or when their bundle is stopping&lt;br /&gt;
* Always indicate requested/provided packages versions&lt;br /&gt;
* Avoid &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; class members&lt;br /&gt;
** &amp;lt;code&amp;gt;private static&amp;lt;/code&amp;gt; are allowed&lt;br /&gt;
** Use interfaces to declare constants&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
	<entry>
		<id>https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_4&amp;diff=7102</id>
		<title>Tutorial OSGi avec Apache Felix - Partie 4</title>
		<link rel="alternate" type="text/html" href="https://air.imag.fr/index.php?title=Tutorial_OSGi_avec_Apache_Felix_-_Partie_4&amp;diff=7102"/>
		<updated>2012-12-20T08:51:39Z</updated>

		<summary type="html">&lt;p&gt;Calmant: /* II. Pure-OSGi service */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tutorial OSGi avec Apache Felix|Revenir au sommaire]]&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
&lt;br /&gt;
* Felix Framework Distribution (voir [[Tutorial OSGi avec Apache Felix - Partie 1]])&lt;br /&gt;
** with the iPOJO Core bundle[http://felix.apache.org/site/download.html] (see next section)&lt;br /&gt;
* [http://www.eclipse.org/downloads/ Eclipse].&lt;br /&gt;
** To support OSGi development, Eclipse needs the &#039;&#039;&#039;PDE&#039;&#039;&#039; (Plug-in Development Environment) plug-in, bundled in &#039;&#039;Eclipse IDE for Java EE Developers&#039;&#039;&lt;br /&gt;
* iPOJO Nature plug-in for Eclipse, available [https://dl.dropbox.com/u/59622687/org.ow2.chameleon.eclipse.ipojo.updatesite-1.0.1-SNAPSHOT.zip as an archive distribution]&lt;br /&gt;
** Install the &#039;&#039;iPOJO Project Nature&#039;&#039; and &#039;&#039;iPOJO Nature Dependencies&#039;&#039; plug-ins&lt;br /&gt;
&lt;br /&gt;
==Set up your Felix installation==&lt;br /&gt;
&lt;br /&gt;
# Run Felix using the following command in the Felix installation directory&lt;br /&gt;
#* &amp;lt;code&amp;gt;java -jar bin/felix.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
# Install iPOJO, using the following Felix Gogo shell commands:&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:list&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix Log Service&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix iPOJO&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix iPOJO Gogo Command&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Useful Gogo commands==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note&#039;&#039;: To ease shell lines edition on Linux, you might use the [http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap rlwrap] tool: &amp;lt;code&amp;gt;rlwrap java -jar bin/felix.jar&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;help {command}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Print the help of the given command&lt;br /&gt;
* &amp;lt;code&amp;gt;lb&amp;lt;/code&amp;gt;&lt;br /&gt;
** Lists the bundles installed in the framework&lt;br /&gt;
* &amp;lt;code&amp;gt;inspect capability service {bundle ID}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Lists the services provided by the given bundle&lt;br /&gt;
** &amp;lt;code&amp;gt;capability&amp;lt;/code&amp;gt; can be written &amp;lt;code&amp;gt;c&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;inspect requirement service {bundle ID}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Lists the services consumed by the given bundle&lt;br /&gt;
** &amp;lt;code&amp;gt;requirement&amp;lt;/code&amp;gt; can be written &amp;lt;code&amp;gt;r&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:factories&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the publicly available iPOJO factories&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:factory {factory name}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the details of the given iPOJO factory&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:instances&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the names and states of iPOJO instances&lt;br /&gt;
* &amp;lt;code&amp;gt;ipojo:instance {instance name}&amp;lt;/code&amp;gt;&lt;br /&gt;
** Prints the details of the given iPOJO component instance&lt;br /&gt;
&lt;br /&gt;
==Eclipse Configuration==&lt;br /&gt;
&lt;br /&gt;
By default, Eclipse uses its installation directory as the Target Platform, i.e. the group of bundles accessible by your bundle project.&lt;br /&gt;
You should declare the installation folder of the Felix Framework as the target platform to avoid compilation and access rights errors.&lt;br /&gt;
&lt;br /&gt;
# Open Eclipse preferences&lt;br /&gt;
# Plug-in Development &amp;gt; Target Platform&lt;br /&gt;
# Add...&lt;br /&gt;
## Create an empty target platform (check &#039;&#039;nothing...&#039;&#039;)&lt;br /&gt;
## Add the &#039;&#039;bin&#039;&#039; and &#039;&#039;bundle&#039;&#039; folders of your Felix installation to the Target Platform&lt;br /&gt;
# Set the new target platform as the current one&lt;br /&gt;
&lt;br /&gt;
=I. Activator=&lt;br /&gt;
&lt;br /&gt;
# Create an Eclipse Plug-in project &#039;&#039;fr.erods.tp.bundle1&#039;&#039;&lt;br /&gt;
#* New &amp;gt; Plug-in project&lt;br /&gt;
#* Select the option &amp;quot;Target Platform&amp;quot; &amp;gt; &amp;quot;an OSGi framework&amp;quot; &amp;gt; &#039;&#039;standard&#039;&#039;&lt;br /&gt;
#* Next&lt;br /&gt;
#* Check &amp;quot;Generate an activator&amp;quot;&lt;br /&gt;
#* Finish&lt;br /&gt;
# Open the activator class and print some text when the bundle starts and stops&lt;br /&gt;
# Export the bundle JAR file with iPOJO Nature&lt;br /&gt;
#* Right click on the bundle project &amp;gt; Export &amp;gt; iPOJO Bundle&lt;br /&gt;
#* Choose an output folder (the Felix installation folder)&lt;br /&gt;
#* Finish&lt;br /&gt;
# Install and test the bundle using the Felix shell (start/update/stop)&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* Indicate when start() and stop() methods are called.&lt;br /&gt;
* Why the BundleContext can be kept as a &amp;lt;code&amp;gt;private static&amp;lt;/code&amp;gt; class member ?&lt;br /&gt;
&lt;br /&gt;
=II. Pure-OSGi service=&lt;br /&gt;
&lt;br /&gt;
# Create an new bundle project &#039;&#039;fr.erods.tp.api&#039;&#039;.&lt;br /&gt;
#* Activator is not needed: uncheck &amp;quot;Generate an activator&amp;quot; in step 2&lt;br /&gt;
# Create the &amp;lt;code&amp;gt;fr.erods.tp.api.IScheduleService&amp;lt;/code&amp;gt; interface with two methods:&lt;br /&gt;
#* &amp;lt;code&amp;gt;int createJob(Runnable aRunnable, int aDelay)&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;void deleteJob(int aId)&amp;lt;/code&amp;gt;&lt;br /&gt;
# Export the API package&lt;br /&gt;
#* Open the Manifest.mf file of &#039;&#039;fr.erods.tp.api&#039;&#039;&lt;br /&gt;
#* In tab &amp;quot;Runtime&amp;quot; &amp;gt; &amp;quot;Exported Packages&amp;quot; &amp;gt; Add&lt;br /&gt;
#** Select the &amp;lt;code&amp;gt;fr.erods.tp.api&amp;lt;/code&amp;gt; package&lt;br /&gt;
# Implement the service in bundle 1&lt;br /&gt;
#* Create the class &amp;lt;code&amp;gt;fr.erods.tp.bundle1.ScheduleImpl&amp;lt;/code&amp;gt;, implementing &amp;lt;code&amp;gt;IScheduleService&amp;lt;/code&amp;gt; in the bundle 1.&lt;br /&gt;
# Register the service with the activator of bundle 1&lt;br /&gt;
#* see [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#registerService%28java.lang.Class,%20S,%20java.util.Dictionary%29 registerService()]&lt;br /&gt;
#* see [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/ServiceRegistration.html#unregister%28%29 unregister()]&lt;br /&gt;
# Implement a service consumer in a new bundle&lt;br /&gt;
#* Create project &#039;&#039;fr.erods.tp.bundle2&#039;&#039;&lt;br /&gt;
#* Import the API package&lt;br /&gt;
#** In the Manifest.mf file of bundle 2&lt;br /&gt;
#** In tab &amp;quot;Dependencies&amp;quot; &amp;gt; &amp;quot;Imported Packages&amp;quot; &amp;gt; Add&lt;br /&gt;
#** Select the &amp;lt;code&amp;gt;fr.erods.tp.api&amp;lt;/code&amp;gt; package&lt;br /&gt;
#* Implement a &amp;lt;code&amp;gt;Consumer&amp;lt;/code&amp;gt; class, implementing the OSGi &amp;lt;code&amp;gt;ServiceListener&amp;lt;/code&amp;gt;[http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/ServiceListener.html] interface&lt;br /&gt;
#* Print a message when the service is bound/unbound&lt;br /&gt;
# Test the bundles in Felix&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* What happens when the consumer is started after the service bundle and why ?&lt;br /&gt;
* Correct this behavior, using [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#getServiceReference%28java.lang.Class%29 getServiceReference()] and [http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#getService%28org.osgi.framework.ServiceReference%29 getService()]&lt;br /&gt;
&lt;br /&gt;
=II. iPOJO: provide and consume with iPOJO=&lt;br /&gt;
&lt;br /&gt;
# Add the iPOJO Nature to projects &#039;&#039;bundle 1&#039;&#039; and &#039;&#039;bundle 2&#039;&#039;&lt;br /&gt;
#* Select the projects&lt;br /&gt;
#* Right click &amp;gt; Add iPOJO Nature&lt;br /&gt;
#* Check &#039;&#039;Use annotations&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Consumer==&lt;br /&gt;
&lt;br /&gt;
# Implement a &amp;lt;code&amp;gt;ConsumerIpojo&amp;lt;/code&amp;gt; class in bundle 2&lt;br /&gt;
#* See [http://felix.apache.org/site/how-to-use-ipojo-annotations.html How to use iPOJO Annotations]&lt;br /&gt;
#* The component must be instantiated automatically&lt;br /&gt;
#* Print a message when the component is (in)validated and when the service is (un)bound&lt;br /&gt;
# Test&lt;br /&gt;
# Set the service requirement as optional&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* Why are the callbacks called in that order ?&lt;br /&gt;
* What happens if you use a missing optional requirement ?&lt;br /&gt;
&lt;br /&gt;
==Provider==&lt;br /&gt;
&lt;br /&gt;
# Implement a &amp;lt;code&amp;gt;ServiceProviderIpojo&amp;lt;/code&amp;gt; class in bundle 1&lt;br /&gt;
#* See [http://felix.apache.org/site/how-to-use-ipojo-annotations.html How to use iPOJO Annotations]&lt;br /&gt;
#* The component must be instantiated automatically&lt;br /&gt;
#* The component must provide its service&lt;br /&gt;
#* Print a message when the component is (in)validated&lt;br /&gt;
# Test&lt;br /&gt;
# Add a &#039;&#039;service controller&#039;&#039; and alternate the service presence&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
Question:&lt;br /&gt;
* How does the consumers react to the service presence cycle ?&lt;br /&gt;
&lt;br /&gt;
==Bonus==&lt;br /&gt;
&lt;br /&gt;
# Add a &amp;quot;service.ranking&amp;quot; property to the pure-OSGi and the iPOJO service, and an &amp;quot;implementation&amp;quot; property to identify them&lt;br /&gt;
# Print the name of the implementation the consumers are bound to&lt;br /&gt;
# Modify the ranking value&lt;br /&gt;
&lt;br /&gt;
Question:&lt;br /&gt;
* How does a service the service selection works ?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note&#039;&#039;: The consumer should call methods of the service and traces should be printed in order to show which service the consumer is bound to.&lt;br /&gt;
&lt;br /&gt;
=III. Whiteboard pattern=&lt;br /&gt;
&lt;br /&gt;
# Create interface &amp;lt;code&amp;gt;IJobListener&amp;lt;/code&amp;gt; in the API package, with two methods:&lt;br /&gt;
#* &amp;lt;code&amp;gt;void onJobCreation(int aId)&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;void onJobDeletion(int aId)&amp;lt;/code&amp;gt;&lt;br /&gt;
# Create a new bundle project &#039;&#039;fr.erods.tp.bundle3&#039;&#039;&lt;br /&gt;
#* Add the iPOJO Nature and annotations&lt;br /&gt;
#* Let it import the API package&lt;br /&gt;
# Create a component providing an &amp;lt;code&amp;gt;IJobListener&amp;lt;/code&amp;gt; service in bundle 3&lt;br /&gt;
# Add job creation / deletion operations in a consumer&lt;br /&gt;
&lt;br /&gt;
==Subscription pattern==&lt;br /&gt;
&lt;br /&gt;
# Modify the schedule component to allow listeners registration:&lt;br /&gt;
#* &amp;lt;code&amp;gt;void addListener(IJobListener)&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;void removeListener(IJobListener)&amp;lt;/code&amp;gt;&lt;br /&gt;
# Register component of bundle 3 as a job listener&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
==Whiteboard pattern==&lt;br /&gt;
&lt;br /&gt;
# Modify the schedule component (in bundle 1)&lt;br /&gt;
#* Remove the registration methods created above&lt;br /&gt;
#* Add a requirement to an array of &amp;lt;code&amp;gt;IJobListener&amp;lt;/code&amp;gt;s, as an optional requirement&lt;br /&gt;
#* Notify them on job creation/deletion&lt;br /&gt;
# Test&lt;br /&gt;
&lt;br /&gt;
Questions:&lt;br /&gt;
* What are the pros/cons of the whiteboard pattern vs. the subscription pattern ?&lt;br /&gt;
* Bonus: compare this whiteboard pattern implementation with the iPOJO Whiteboard pattern handler[http://felix.apache.org/site/white-board-pattern-handler.html]&lt;br /&gt;
&lt;br /&gt;
=IV. JMX MBean with iPOJO=&lt;br /&gt;
&lt;br /&gt;
# Create a new bundle, with iPOJO Nature and annotations&lt;br /&gt;
# Create a component, which doesn&#039;t provide any service, but contains public methods to create/delete/list &amp;lt;code&amp;gt;IScheduleService&amp;lt;/code&amp;gt; jobs&lt;br /&gt;
# Use iPOJO JMX annotations[http://felix.apache.org/site/how-to-use-ipojo-annotations.html#HowtouseiPOJOAnnotations-ExposinginstancesasaJMXMBean%28externalhandler%29] to export those methods&lt;br /&gt;
# You will need the iPOJO JMX handler to test this component: install it using the following command in the Felix shell:&lt;br /&gt;
#* &amp;lt;code&amp;gt;obr:deploy -s &amp;quot;Apache Felix iPOJO JMX Handler&amp;lt;/code&amp;gt;&lt;br /&gt;
# Install the bundle in the Felix framework&lt;br /&gt;
# Run &amp;lt;code&amp;gt;jconsole&amp;lt;/code&amp;gt; (in the Oracle Java distribution) or &amp;lt;code&amp;gt;jvisualvm&amp;lt;/code&amp;gt; (in the Oracle Java distribution) or &amp;lt;code&amp;gt;visualvm&amp;lt;/code&amp;gt;[http://visualvm.java.net/download.html]&lt;br /&gt;
#* You might need to install the JMX plug-in in VisualVM:&lt;br /&gt;
#** Tools &amp;gt; Plugins &amp;gt; Available Plugi-ns&lt;br /&gt;
#** Install the &#039;&#039;VisualVM-MBeans&#039;&#039; plug-in&lt;br /&gt;
# Connect VisualVM to your Felix JVM and play with the JMX beans&lt;br /&gt;
&lt;br /&gt;
=V. Gogo Command with iPOJO=&lt;br /&gt;
&lt;br /&gt;
# Create a new bundle, with iPOJO Nature and annotations&lt;br /&gt;
# Create a Gogo command provider to create and delete jobs, and to list current jobs status&lt;br /&gt;
&lt;br /&gt;
==Minimal Gogo command component==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Component;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Instantiate;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.Provides;&lt;br /&gt;
import org.apache.felix.ipojo.annotations.ServiceProperty;&lt;br /&gt;
import org.apache.felix.service.command.Descriptor;&lt;br /&gt;
&lt;br /&gt;
@Component(immediate = true)&lt;br /&gt;
// Provide the component class as a service&lt;br /&gt;
@Provides(specifications = ListComponentsCommand.class)&lt;br /&gt;
// Instantiate the component automatically&lt;br /&gt;
@Instantiate&lt;br /&gt;
public class ListComponentsCommand {&lt;br /&gt;
&lt;br /&gt;
    // Gogo scope/namespace&lt;br /&gt;
    @ServiceProperty(name = &amp;quot;osgi.command.scope&amp;quot;, value = &amp;quot;test&amp;quot;)&lt;br /&gt;
    String scope;&lt;br /&gt;
&lt;br /&gt;
    // Gogo commands provided by this class (must be methods names)&lt;br /&gt;
    @ServiceProperty(name = &amp;quot;osgi.command.function&amp;quot;, value = &amp;quot;{}&amp;quot;)&lt;br /&gt;
    String[] function = new String[] { &amp;quot;test&amp;quot; };&lt;br /&gt;
&lt;br /&gt;
    // Method description&lt;br /&gt;
    @Descriptor(&amp;quot;test&amp;quot;)&lt;br /&gt;
    public void test() {&lt;br /&gt;
        System.out.println(&amp;quot;test!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=VI. Config Admin with iPOJO=&lt;br /&gt;
&lt;br /&gt;
See [http://felix.apache.org/site/combining-ipojo-and-configuration-admin.html Combining iPOJO and Configuration Admin]&lt;br /&gt;
&lt;br /&gt;
=VII. Event Admin with iPOJO=&lt;br /&gt;
1. Create a new bundle, with iPOJO annotations to send events on jobs status changes&lt;br /&gt;
&lt;br /&gt;
=VIII. Extender with iPOJO=&lt;br /&gt;
??&lt;br /&gt;
&lt;br /&gt;
=Guidelines &amp;amp; Good Practices (&amp;quot;OSGi Zen&amp;quot;)=&lt;br /&gt;
&lt;br /&gt;
* Always separate API and implementations&lt;br /&gt;
* Always release services and resources once you&#039;re done or when their bundle is stopping&lt;br /&gt;
* Always indicate requested/provided packages versions&lt;br /&gt;
* Avoid &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; class members&lt;br /&gt;
** &amp;lt;code&amp;gt;private static&amp;lt;/code&amp;gt; are allowed&lt;br /&gt;
** Use interfaces to declare constants&lt;/div&gt;</summary>
		<author><name>Calmant</name></author>
	</entry>
</feed>