Thématiques principales

mercredi 31 janvier 2018

Devenir maître de conférence

Je viens de finir de lire un article des Echos.fr [4] publié en octobre dernier sur l'état de la recherche française. Et je constate que depuis que j’ai soutenu mon doctorat en 2010, rien n’a changé et c’est même pire. Je m’explique.

Pour reprendre un peu l’historique de mon parcours, j’ai suivi comme beaucoup une filière scientifique en pensant faire de la “méca”, après avoir eu mon lot de galère en prépa, je suis parvenu à intégrer une école d’ingénieur, l’ENSISA (ou ESSAIM a l'époque) [1], Certes, ce n'était pas une école située dans le haut du classement mais avec le recul, je peux affirme qu’elle n’a pas à rougir des enseignements qu’elle donne car j’estime avoir reçu un bagage scientifique en automatique et informatique, vraiment très solide.

A cette époque, la recherche m'intéressait et a l’issu de l’obtention de mon diplôme d’ingénieur, j’ai souhaité le compléter par un second bac+5 en faisant un DEA (ou master recherche) et il faut savoir que pour pouvoir faire de la recherche en France, il faut pour pouvoir poursuivre en doctorat, avoir ce diplôme spécifiquement (qui sert un peu de première marche aux activités de la recherche). A noter que la règle s’est un peu assouplie (au vue de la pénurie de candidats), et que sous conditions, il est possible de déposer un dossier de candidature avec un Master Pro ou même un diplôme d'ingénieur [2]. Mais tout cela reste à l'appréciation de l'Ecole doctorale et la voie classique sera toujours de se présenter avec un Master Recherche, ce que j’ai fais.

On voit ici qu’avant même de postuler pour faire un doctorat, il va exister un certains nombres de filtres qui, il me semble, se justifie effectivement par les enjeux en terme de travail et d’investissement que va nécessiter le doctorat,  je vous laisse lire cet article pour comprendre les enjeux réel d’un doctorat [3]

Il faut savoir que contrairement à ce qui peut être penser, le doctorat n’est pas une activité pédagogique diplômante comme les autres, comme les autres cursus universitaire. Le doctorat doit être considéré comme d’une activité professionnel diplômante que je comparerai sans problème avec un projet de création d’entreprise avec peut être une contrainte financière moins forte.

Le rôle de l’ecole doctorale et de l’encadrement est primordial  car il ne s’agit pas de faire bosser des jeunes gens sur des sujets pendant 3 ou 4 ans sans leur donner les moyens de travailler sereinement. Cette étape est primordiale car elle assure un financement et un revenu au doctorant.

La notion de contrainte financière doit malgré tout être nuancé car si il est rare qu’une thèse soit réalisée sans financement, du moins dans les sciences dites dures, elles le sont malheureusement trop souvent dans les sciences molles comme l’art ou la littérature… Et une nouvelle fois, le propos est à nuancer, car pour ma part j’ai eut droit à une bourse ministérielle (le meilleur type de bourse) pour financer ma thèse et celle ci s'élevait à 1300€ net (la source [5], actualisée, correspond bien a mon souvenir ). En réalisant un monitorat [6] (l'équivalent d’un demi service d’enseignement d’un maître de conférence [7]), le doctorant pourra alors espérer voir son salaire monter a 2024€ brut soit 1600 € net par mois…

Bien au delà d’avoir deux bac+5 et d’aller vers un bac+8, on peut quand même se demander comment économiquement, les gens acceptent de faire une thèse pour un tel revenu alors qu’en allant dans l’industrie, celui ci sera facilement de 100 a 500 € plus élevé sans compter les revalorisations annuelles qui en thèse, n’ont pas lieu. Alors pour ma part, c’est la passion de la recherche qui a primé car forcement, il faut être passionné pour ce prix la!

Je vous laisse à cet article [7] faisant le tour du problème du financement de la thèse sachant que les problèmes il y en aura également après, comme le dit l’article, et surtout en France, dans la reconnaissance du diplôme dans le milieu industriel.

Et oui car après avoir accouché de votre manuscrit de thèse, avoir eut la chance de faire quelques publications et avoir soutenu, il va vous falloir, d’une part, faire le deuil de votre travail de 3 ou 4 années et faire le point sur votre avenir. J'évoque ici deux points pour lesquels je n'étais pas préparé. Le premier, plus personnel, est que je n’avais pas envisager la fin de mes travaux. En effet, pour mener à bien un doctorat, le sujet doit devenir une préoccupation quasi omniprésente et il vous accompagne partout, tout le temps, sauf que une fois soutenue, et bien tout s'arrête, vous êtes docteur et votre sujet n’est plus vraiment la vous laissant vide, un peu dépossédé de votre travail et pourtant il vous faut rebondir et enchaîner professionnellement.

Le deuxième point est comme vous l’avez compris plus matériel. Que faire après la thèse? Alors c’est maintenant que les choses deviennent presque aberrante. Pourquoi? Parce que nous sommes en France.

En effet, lorsque vous finissez votre thèse, plusieurs possibilités s’offrent à vous : le monde industriel, le monde académique, ou un denier monde a mis chemin entre le deux.

Chacun de ses mondes a des avantages mais aussi des inconvénients. Voyons lesquels.

Alors autant vous le dire tout de suite (parce que c’est celui que j’ai choisi), c’est le monde industriel qui sera probablement le plus ouvert a vous recruter et pour un salaire qui sera plus qu’honorable. Alors bien sûr, a âge égal, il existe un gap technique entre le jeune docteur et l'ingénieur mais ce gap se comble rapidement, et lors de l’entretien il importe de vendre ses compétences de docteur avant tout. Ainsi je vous invite a reprendre l’article [3] pour faire le point cependant si cette solution est la plus accessible (enfin il me semble) il vous faudra faire le deuil de votre activité de recherche, en sachant que celle ci sera d'autant plus difficile a reprendre plus tard.

Du coup avant de partir dans le monde industriel, il est très important de ne pas lâcher votre activité de recherche en poursuivant votre travail de publication et de vous intéresser sérieusement aux procédures permettant de postuler aux postes de Maître de conférence. Il est même important de s’y intéresser bien avant de soutenir car le chemin pour accéder à ce type de poste est long et laborieux. A titre personnel, j’avoue ne pas avoir même essayé de le parcourir car je me suis laissé séduire par le monde industriel qui me semblait à l'époque me donner de meilleurs et plus belles opportunités cependant, aujourd’hui avec le recul, je me rend compte que j’aurai dû au moins tenter l’aventure et aller jusqu’au bout.

Mais alors pourquoi est ce si dur d’obtenir un poste de maître de conférence (et être enseignant chercheur) ? C’est simple et c’est d'écrit sur ces liens [8] et [9], vous devez avant toute chose, en plus d’avoir porter votre sujet de thèse pendant au moins trois années, effectuer publications et conférences et soutenir votre thèse, obtenir auprès du CNU (Conseil National des Universités) une ou plusieurs qualifications dans la ou les sections auprès desquelles votre travail (de thèse mais aussi d’enseignement) peut se rapprocher.

Par exemple, les sections auxquelles j’aurais pu éventuellement postuler sont les section 27 (informatique) et 61 (automatique). Pour cela, cependant, il aurait fallu produire (donc en plus de la soutenance de thèse qui soumet déjà le futur docteur a un jury constitué d’un président de jury, de deux rapporteurs et de ses encadrants de thèse, avec les relectures et retours qui vont de pairs) un dossier pour chacun des trois rapporteurs qui vont la aussi constituer un jury pour chaque section CNU auquel on voudra postuler. Le dossier en question devant être constitué pour une date spécifique avec bien sur, la thèse, un dossier pédagogique, faisant le tour des enseignements que l’on aura prodiguer à l’université, les publications (en étant bien sûr regardant sur le niveau des journaux ou elles ont été publiées, la participation aux conférences n'étant plus autant valorisée) et un CV, bien sur.

Alors attention, les dates doivent être respecté car sinon il faudra attendre l’année suivante avec bien sur une mise a jours des publications et enseignements donc il vous faudra etre rester dans le monde universitaire et sa précarité (bienvenu dans les postdoc et autres ATER…. et la difficile tâche de donner de la cohérence à vos travaux, ce que l’on vous demandera) car sans qualification, il est impossible de postuler aux postes de maîtres de conférences.

Alors voilà, vous voici qualifié, vous faites partie de la bonne moitié des docteurs ayant la possibilité pour les quatre années à venir de postuler à des postes de maître de conférence. A partir de maintenant, vous allez alors maintenant vous engager sur la dernière et plus longue étape de votre parcours. Il va falloir chercher des postes sur le portail Galaxie [10], et pour chaque laboratoire ou les thématiques de recherche vous intéresse, préparer une présentation de vos travaux ainsi que la projection de votre travail dans la thématique du labo. Ceci est loin d'être aisé car nécessite un travail en amont conséquent en terme d'état de l’art des publications majeurs des différents labo et également une bonne appréciation de leur politique de recherche et leurs objectifs a plus ou moins long terme (ba oui si vous postulez c’est que vous comptez vous y installer… au moins pour quelques années….) Voila et tout cela, en ayant une activité parallèle de recherche et d’enseignement…. pour un salaire ne dépassant pas 2000€ net…. en ayant presque 30 ans… avec peut être une vie de famille qui doit subir les déménagement suite au changement de poste (postdoc). L'age moyen de l'obtention du poste de maitre de conf est de 33 ans [11]... alors que l'age moyen pour la soutenance est 29 ans, ... donc pendant 4 ans, vous allez enchainer entre 2 et 4 contrats, d'ATER et postdoc pas forcement la ou vous avez fait votre thèse (ça serai trop simple...), on peut se demander qui a 30 ans, n'a pas encore de vie de famille??

Alors il reste un monde intermédiaire entre celui monde industriel et le monde universitaire qui se situe dans les laboratoires privés (mais rare) et publiques non universitaire comme le CNRS ou l’INRIA pour lesquels les salaires seront un peu meilleur mais pour lesquels il faudra sacrifier la composante enseignement, qui est a mon sens une composante réellement enrichissante et vraiment sous valorisée.

A l’heure actuelle, pourtant, après être passé par le monde industriel, je pense que la recherche reste par principe, largement plus enrichissante intellectuellement car ne se limitant pas à des éléments technologiques. On voit même que la recherche française se porte bien sur le plan de la qualité, mais ceci grâce a des passionnés qui faute de bois sec pour garder leur feux allumés n’auront peut être d’autre choix, comme moi, d'aller dans des secteurs soit pas toujours adaptés [7] aux profils des docteurs.

Je ne désespère pas pourtant qu’un jour on redonne à la recherche et aux chercheurs plus de moyens et plus de simplicité pour pouvoir réaliser leur travail et pourquoi pas un jour y revenir.

References


[1] http://www.ensisa.uha.fr/
[2] http://www.univ-toulouse.fr/recherche-doctorat/doctorat/faire-un-doctorat-toulouse
[3] http://www.doctorat.be/fr/espace-doctorant/faire-ou-ne-pas-faire-une-th%C3%A8se
[4] https://www.lesechos.fr/11/10/2017/LesEchos/22548-031-ECH_l-inquietante-precarisation-de-la-recherche-francaise.htm
[5] http://www.enseignementsup-recherche.gouv.fr/cid76053/le-financement-doctoral.html
[6] http://www.studyrama.com/vie-etudiante/budget-etudiant-financer-ses-etudes/les-bourses-et-aides-publiques/le-service-d-enseignement-du-contrat-doctoral-ex-monitorat-1162468
[7] http://etudiant.lefigaro.fr/article/le-doctorat-un-diplome-qui-rapporte-peu_3df597a0-1843-11e7-88d6-e7c3ba8773d7/
[8] http://www.enseignementsup-recherche.gouv.fr/cid22646/maitres-de-conferences-et-professeurs-des-universites-recrutement-agregation-detachement-mutations.html#Recrutement
[9] http://www.enseignementsup-recherche.gouv.fr/cid22657/maitres-de-conferences.html
[10] https://www.galaxie.enseignementsup-recherche.gouv.fr/ensup/cand_recrutement.htm
[11] https://publication.enseignementsup-recherche.gouv.fr/eesr/7/EESR7_ES_06-qualification_et_recrutement_des_enseignants_chercheurs.php
[12] https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0ahUKEwjTv_zOvYLZAhXGRhQKHXrMD4cQFggqMAE&url=https%3A%2F%2Ff-origin.hypotheses.org%2Fwp-content%2Fblogs.dir%2F233%2Ffiles%2F2012%2F09%2Flinsertion-par-Ecoles-Doctorales.pdf&usg=AOvVaw23MkXMavsvx02avppm8gLM

mardi 30 janvier 2018

Test d'IHM : fest-util

Effectuer des tests unitaires est une tâche indispensable mais qui peut souvent s'avérer un vrai casse tête lorsqu’il s’agit de traiter des IHM.

En Java standard il existe une librairie de test dédiée au IHM de type client lourd pour les API swing et awt qui s’appele Fest [1] [3]. Celle est vraiment concu pour etre simple et logique en utilisant les noms des éléments de l’IHM pour se mapper sur leur interfaces de fonctionnement.

Pour l’utiliser il suffit de tirer l'artefact suivant:
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-util</artifactId>
<version>1.1.6</version>
<scope>test</scope>
</dependency>
Pour l’utiliser il reste à définir une classe de test classique JUnit héritant de la classe FestSwingJUnitTestCase dans laquelle il faudra initialiser un robot Fest et le donner à un objet de type FrameFixture qui va se charger de piloter le robot afin que celui ci parse et effectuer les interaction adéquate sur notre IHM.

Avant cela, Pour que le robot soit capable de parser notre IHM il faudra par contre indiquer a Fest sur quel IHM il doit faire ses actions (grâce a un GuiQuery). On spécifie alors une méthode statique d’initialisation dédié dans laquelle nous instancierons notre IHM:
@RunsInEDT
private static MainFrame createNewEditor(BundleContext context) {
final GuiQuery<MainFrame> query = new GuiQuery<MainFrame>() {
@Override
protected MainFrame executeInEDT() {
MainFrame app = null;
try {
app = new MainFrame(context);
} catch (final TcOsgiException e) {
e.printStackTrace();
}
return app;
}
};
return GuiActionRunner.execute(query);
}
Du coup, il nous faudra initialiser dans un setUp notre environnement de test contenant le FrameMixture:
@Override
protected void onSetUp() {
try {
BundleContext context = Mockito.mock(BundleContext.class);
editor = new FrameFixture(robot(), MainFrameTest.createNewEditor(context));
editor.show();
} catch (Exception e) {
e.printStackTrace();
}
}
Grace a cela, il ne nous restera plus qu’a declarer les actions que l’on souhaitera faire sur l’IHM dans des tests spécifiques comme on le ferait dans un test unitaire classique sauf que la nous allons scénariser les actions:
@Test
public void profilCreationSelection() {
editor.menuItem("Select MorphMath Action").click();
editor.comboBox("combo1").selectItem("dilatation").click();
editor.menuItem("GO").click();
System.out.println(new File(".").getAbsolutePath());
editor.fileChooser().fileNameTextBox().setText(
"docvierge.bmp");
editor.fileChooser().approve();
Thread.sleep(500);
editor.close();
}
A noter qu'à ce niveau d’abstraction, nous ne sommes plus vraiment en train de faire des tests unitaires mais plutôt des tests fonctionnels mais cela n’a pas forcement d’importance dans notre cas (a noter malgré tout que l’approche est particulièrement adapté à la mise en place de test pour vérifier des cas d’utilisation particulière en lien direct avec le besoin utilisateur)

Voila un petit aperçu de Fest et de ses capacités pour des tests d’IHM. Point particulier a prendre en compte lors de l'exécution des tests: ces derniers sont réalisés avec une IHM visible vous permettant de voir quels sont les actions et mouvement de souris réalisées pour faire le test. Cela est clairement intéressant mais comporte un inconvénient majeur, vos tests ne fonctionnent pas sans environnement graphique comme dans un serveur d'intégration continu. Typiquement vous aurez une erreur du type (dans Travis [2] par exemple):

PM org.fest.swing.monitor.WindowStatus <init>
WARNING: Error ocurred when creating a new Robot
java.awt.AWTException: headless environment
at java.awt.Robot.<init>(Robot.java:91)
at org.fest.swing.util.RobotFactory.newRobotInPrimaryScreen(RobotFactory.java:35)
at org.fest.swing.monitor.WindowStatus.<init>(WindowStatus.java:58)
at org.fest.swing.monitor.WindowStatus.<init>(WindowStatus.java:51)
at org.fest.swing.monitor.WindowMonitor.<init>(WindowMonitor.java:51)
at org.fest.swing.monitor.WindowMonitor$SingletonLazyLoader$1.executeInEDT(WindowMonitor.java:134)
at org.fest.swing.monitor.WindowMonitor$SingletonLazyLoader$1.executeInEDT(WindowMonitor.java:132)
at org.fest.swing.edt.GuiQuery.run(GuiQuery.java:41)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Pour résoudre ce problème il vous suffira d’utiliser xvfb (un server X11) [4] . Comme décrit dans [5], cela permet de simuler un environnement graphique. (ou un autre exemple [6]).

References:

[1] http://www.vogella.com/tutorials/FEST/article.html
[2] https://travis-ci.org/
[3] http://tuhrig.de/automated-ui-testing-with-swing-fest/
[4] https://www.x.org/archive/X11R7.6/doc/man/man1/Xvfb.1.xhtml
[5] https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI
[6] https://gist.github.com/cecilemuller/764afa5d4c67e17741d9bc258b45cdc1

dimanche 28 janvier 2018

Gradle

Lors de la production de systèmes logiciels, il ne fait aucun doute que la phase la plus importante est la compilation qui nécessite l’utilisation d'outils tels que gcc ou javac. Aujourd’hui pourtant limiter la production d’un logiciel a la compilation n’est plus suffisant. De nombreuses phases périphériques à la compilation sont devenu indispensables, comme l'exécution des tests unitaires ou des tests fonctionnels, la production automatique de documentations ou de code, le packaging multi plateforme, ou même la mise en production. Ceci s'appelle l'intégration continu au sein duquel on va trouver divers outils à différents niveau d’abstraction (Jenkins[1] , artifactory [2]) ou differents roles (Sonar [3], RobotFramework [4]). Nous reviendrons sur ces outils, mais nous en avions déjà vu un nommé Maven dans un précédent article [5] dont le but est justement de couvrir l’ensemble des phases du build.

Aujourd’hui nous allons nous intéresser à ce que l’on pourrait appeler un peu abusivement son concurrent: Gradle [7].

A mon sens Gradle en est plutot le successeur et nous verrons pourquoi. En effet, même si personnellement j’utilise encore beaucoup Maven, les raisons sont surtout historique et que faire la migration de l’un vers l’autre, ne peut être qu’un bien [9] mais cela repose sur une bonne disponibilité en temps.

Voyons ce que propose Gradle par dela Maven. Pour faire simple et rapide sur l'intérêt de Gradle est qu’il permet de dépasser le côté monolithe de Maven. En effet, Maven repose sur un socle stable et très sain d’un process de build. Du moins lorsque ce processus est classique et standard. Gradle, tout en conservant ce socle permet d'être plus souple et dynamique car contrairement a Maven qui repose sur xml pour décrire le contenu du build (donc a une vision configuration du process), Gradle lui repose sur groovy qui est lui un langage de programmation.

En fait si l’on reprend le titre de la publication de Leon Osterweil:  “software processes are software too” [8], nous sommes face à un véritable changement de paradigme dans la façon de gérer la production de logiciel ou celle-ci est également vu comme une partie intégrante du logiciel lui même.

Par exemple, Google a adopté Gradle pour la production de ses applicatifs Android et l’on peut assister que cette adoption a été largement suivi par une très bonne intégration de ce nouvel outils dans les IDE standard de la communauté. Ainsi developper une application android sous Gradle n’est vraiment pas un probleme [11] (nous y reviendrons dans un futur article)

Initialisation

Avant de nous pencher sur android, regardons déjà comment faire le build d’une application java standard avec Gradle.

Il faut commencer par télécharger Gradle [12] et d’ajouter son GRADLE_HOME/bin au PATH du système. Ceci permettra de lancer gradle en ligne de commande :

gradle -v

Votre installation est bonne? Ok nous allons alors pouvoir initialiser notre premier projet Gradle en lancant la commande init:

gradle init

A la console normalement vous devriez obtenir les log suivant

Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
Support for running Gradle using Java 7 has been deprecated and is scheduled to be removed in Gradle 5.0. Please see https://docs.gradle.org/4.3/userguide/java_plugin.html#sec:java_cross_compilation for more details.
BUILD SUCCESSFUL in 7s
2 actionable tasks: 2 executed

Cette commande va tout d’abord lancer un demon pour accélérer les build suivant du projet et va preinitialiser pour votre système un certain nombre de fichiers, un répertoire wrapper et un répertoire .gradle (invisible sous unix)

ls -a
.  ..  build.gradle  gradle  .gradle  gradlew  gradlew.bat  settings.gradle

Alors commençons par la partie wrapper. Celle ci n’est pas indispensable mais Gradle préconise son utilisation afin de garantir l'homogénéité des builds du projet [13]. Les repertoires et fichiers concernés sont gradle, gradlew et gradlew.bat. En fait le wrapper permet contrairement à Maven,  le rechargement lors du build de la version proposée de gradle qui doit être utilisée pour construire le projet. Ainsi, pour tous les développeurs utilisant le wrapper, le build sera forcément identique (ou du moins reposera sur un environnement identique). Les fichiers gradlew permettent de lancer le wrapper et dans le repertoire nous trouverons un jar (réalisant le maintien de la version) et un fichier de propriétés pour le wrapper (contenant des données d’environnement) [14].

Les fichiers et répertoires participant a proprement parler au build sont build.gradle, settings.gradle et .gradle. Le repertoire .gradle est un repertoire interne a gradle propre au projet permettant à gradle de tagger les fichiers nouvellements modifiés et devant être incorporé au build incremental (c’est lui qui va rendre le processus de build plus efficace et plus rapide également). Normalement il ne devrait pas y avoir de besoin d’aller mettre son nez dedans; par contre, nous arrivons enfin sur les deux fichiers qui nous interesse le plus settings.gradle et build.gradle.

Le fichier settings.gradle est optionnel mais, il est recommandé de systématiquement l’utiliser. En effet celui-ci n’est pas utile pour un projet isolé mais sera indispensable dans le cas des multi-projets (equivalent aux modules maven). De plus il permet de définir un nom aux projets qui par défaut s’il n’existe pas est pris sur la base du nom du repertoire contenant le projet (ce qui n’est pas tiptop…)

settings.gradle

De façon simple voici ce qu’il peut contenir:

/*
// To declare projects as part of a multi-project build use the 'include' method
include 'shared'
include 'api'
include 'services:webservice'
*/
rootProject.name = 'monProjetGradle'

On aura compris que rootProject.name est le nom de notre projet…. A noter la primitive include afin de déclarer des sous projets à construire.

build.gradle

Intéressons nous au fichier de build lui-même: build.gradle. Ce fichier a pour vocation de décrire le contenu du build lui-même en s’appuyant sur la syntaxe Groovy. On imagine alors ce que l’on va y decrire sera considéré avant tout comme du comportement plutôt que de la configuration (a l’inverse de Maven) et c’est effectivement le cas à quelques exception près.

Prenons l’exemple d’un projet Java, il va falloir commencer par indiquer à Gradle que le build s’effectuera en Java. Pour cela, on va lui specifier l’utilisation d’un plugin [15]:

apply plugin: 'java'

Ensuite, à l'instar de maven on pourra donner une description et une version à l’artifact que nous allons créer. A la suite de quoi on va lui donner la version java pour la compilation:

description ="Projet de test pour gradle"
version = '0.1.0-SNAPSHOT'
sourceCompatibility = 1.8

Pour identifier les sources, il est possible de spécifier leur emplacement, ainsi que l’emplacement des tests.

sourceSets {
    main {
         java {
              srcDir 'src/main/java'
              }
         }
    test {
         java {
              srcDir 'src/test/java'
              }
         }
}

Encore une fois comme pour maven, il faut définir quelles vont être les dépendances nécessaires à la compilation et aux tests: Plus simplement que pour maven il suffit de déclarer le bloc dependencies comme suit:

dependencies {
    compile 'org.tc.osgi.bundle.utils:tc-osgi-bundle-utils-interfaces:0.1.0-SNAPSHOT'
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-all:1.9.5'
}

A noter que le nommage des artifacts peut suivre les règles d’ecriture prescrit par Maven et permettre d’utiliser des repository Maven.
C’est d’ailleur ce que l’on va ajouter à notre build, la possibilité d’aller rechercher des artifacts dans un artifactory maven. Ainsi, si vous utilisez un repository maven perso, il faudra le déclarer avec la primitive repositories comme suit:

repositories {
    //jcenter()
    maven {
        url "http://localhost:8081/artifactory/cots"
        credentials {
            username = "toto"
            password = "tata"
        }
   }
}

Voila, et enfin pour les plus aguerri, il est possible de modifier manuellement le Manifest du jar produit. Pour exemple, pour construire des Bundles OSGI (nous regarderons cela dans un autre article sur ce qu’est OSGI) il faudra non seulement rajouter le plugin osgi mais aussi triturer un peu le manifest:

apply plugin: 'osgi'
jar {
    manifest {
    attributes 'Bundle-SymbolicName' : project.name
attributes 'Bundle-Name' : project.name + '-' + version
attributes 'Bundle-Version' : version
attributes 'Bundle-Vendor' : 'TC'
        attributes 'Bundle-Activator': 'org.tc.osgi.bundle.utils.module.activator.UtilsActivator'
        attributes 'Bundle-Description': 'Un bundle pour contenir des services utilitaires'
    }
}

ou plus classiquement pour un jar java standard:

jar {
    manifest {
        attributes 'Main-Class': 'monProjet.Main'
    }
}

Voila, ceci termine la partie statique du build. Maintenant découvrons sa partie dynamique, les taches.

Les taches

Les tâches sont du code groovy permettant d’orchestrer le déroulement du build. Alors bien sur, il ne faudra pas écrire tout le code nécessaire à son exécution. En effet si il existe deux types de tâches, les premières et les plus employées sont celles par défauts déclarer dans les plugins [15] [16].

Ensuite bien sur, il est possible d’en créer soit même avec à terme la définition d’un plugin.. A noter que outre la simplicité évidente du langage, dans le monde maven, il ne serait pas possible d’ajouter du comportement au build sans faire obligatoirement un plugin-maven puisque l’on ne peut ajouter directement du comportement dans le pom (a moins d’utiliser un plugin de type script).

Par exemple voici une petite tache propre a notre build:

// définition d'une tache perso nommé hello
task matache {
    doLast {
        println 'Building ' + project.name
    }
}

Voila il suffira d’appeler la commande

gradle matache

Pour afficher dans la console de build, “Building monProjetGradle”

Voila on a fait le tour de Gradle sans forcement etre rentrer dans le détail mais probablement suffisamment pour pouvoir rapidement mettre en oeuvre un début de build. A mon sens gradle, au vue de sa flexibilité, ne peut que finir par remplacer Maven car il en détient tous les avantages et en complète les défauts (attention par contre a ce que flexibilité ne ressemble pas a chaos). Finalement, son seul tort est peut etre encore son manque de popularité et de visibilité auprès des grands groupes du fait de son “jeune” âge même si la communauté est très active et fournit du contenu riche et très varié.  Pour plus d’informations, n'hésitez pas à consulter [17] [18] qui m’ont été d’une grande aide pour découvrir gradle et écrire cet article.

References:

[1] https://jenkins.io/
[2] https://jfrog.com/artifactory/
[3] https://www.sonarqube.org/
[4] http://robotframework.org/
[5] https://maven.apache.org/
[6] http://un-est-tout-et-tout-est-un.blogspot.com/2017/12/maven-introduction.html
[7] https://gradle.org/releases/
[8] Leon Osterweil:  “software processes are software too”, Proceeding ICSE '87 Proceedings of the 9th international conference on Software Engineering, Pages 2-13
[9] https://dzone.com/articles/gradle-vs-maven?edition=306207&utm_source=Daily%20Digest&utm_medium=email&utm_campaign=dd%202017-07-02
[10] https://devops.com/puzzle-gradle-maven/
[11] http://www.tutos-android.com/maitriser-gradle-partie-1
[12] http://www.gradle.org/downloads
[13] https://docs.gradle.org/current/userguide/gradle_wrapper.html
[14] https://docs.gradle.org/2.4/userguide/build_environment.html#sec:gradle_configuration_properties
[15] https://docs.gradle.org/2.4/userguide/standard_plugins.html
[16] https://plugins.gradle.org/
[17] https://www.petrikainulainen.net/getting-started-with-gradle/
[18] http://www.vogella.com/tutorials/Gradle/article.html

mardi 23 janvier 2018

Pont avec Groovy

Lors de développement logiciel, il arrive que l'on ait besoin de déporter du code dans des scripts de façon a ce que l'application soit plus simple a reconfigurer. Dans le cas du code Java, il est possible également d'affiner des algorithmes dans des scripts groovy.

Cependant ce n'est pas forcement immédiat de coupler les deux langages et il faut passer par un chargeur de scripts.

Pour cela il est nécessaire d'inclure la dépendance maven suivant:


1
2
3
4
5
<dependency>
 <groupId>org.codehaus.groovy</groupId>
 <artifactId>groovy-all</artifactId>
 <verion>2.4.12</version>
</dependency>


Une fois la dépendance mise dans notre pom, il va falloir employer la GroovyShell afin de parser le code groovy. Au passage on pourra donner a notre Shell un Binding afin de remplir les variables éventuelles qui seront a donner aux scripts si ces derniers sont des Templates.

Enfin il faut exécuter le script Groovy pour en récupérer le résultat.

Si l'on considere le script groovy suivant contenu dans le fichier monScript.groovy:

println "hello world," + $argument

Bon ok ca fait pas grand chose, mais c'est pour l'exemple. On notera juste ici, l'emploie de $argument qui devra etre remplacer par un binding.

On va alors elaborer un chargeur pour le script, definir le binding, puis l'executer


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
 Binding binding = new Binding();
 binding.setVariable("$argument", " parceque c'est groovy!");
 GroovyShell shell = new GroovyShell(binding);
 try {
  // Chargement du script groovy
  Script s=shell.parse(new File("src/main/scripts/monScript.groovy"));
  // Exécution du script
  Object retour = s.run();
  // Affichage de la valeur de retour du script
  if(retour!=null)
   System.out.println(retour);
 } catch (CompilationFailedException e) {
  e.printStackTrace();
 } catch (IOException e) {
  e.printStackTrace();
 }
}


Et la console nous donne le résultat d’exécution du script:
hello world, parceque c'est groovy!

dimanche 21 janvier 2018

IA : Les systèmes experts, Drools

Cet article est le premier d’une longue série sur l’intelligence artificielle. Je n’ai pas introduit cette dernière mais je n’y manquerai pas dans un article futur. Je passe donc sur cela pour m’intéresser directement à un axe complet de l’IA que sont les systèmes experts [1] [2].

Les systèmes experts sont ce que l’on appelle dans le domaine de la modélisation, le modèle des comportements d’un expert du domaine. Son rôle est de procéder de la même manière que l’expert afin d'en reproduire l’analyse.

Un système expert va donc consolider la connaissance de l’expert du domaine pour procéder à des traitements conformes à ceux prescrits par ce même expert. Deux concepts clefs des systèmes experts sont identifiables alors:

  • une base de connaissances
  • des règles d'inférences

Selon ces concepts, un système expert croise alors les connaissances avec les règles dans un moteur d'inférence qui peut alors produire soit des nouvelles connaissances, soit de nouvelles règles ou les deux.



jeudi 11 janvier 2018

Encodage des entiers

Petite réaction suite au visionnage d'une vidéo et de ses commentaire traitant de 1+1=0. Comme quoi on peut traiter de sujet intéressant même en partant d'une chose simple.

La vidéo traite de l'encodage du binaire et de l’opérateur addition sur les binaires en passant forcement par l’équivalence entre décimal et binaire. En lisant les commentaires, j'ai vu beaucoup de gens discourir sur l’opération d'addition en elle même dans le cadre informatique.

Pourtant, il me semble qu'il ne faut pas confondre implémentation numérique et le concept mathématique représenté. Ici bien que l'exemple soit traité via un outil ce qui nous donne envie de traiter la question comme d'un problème d'algorithmie logiciel, la notion de codage binaire n'a pas besoin de limite ainsi 1+1 = 10 en binaire et c'est toujours vrai, après si on implémente cet opération avec des boolean (dans n'importe quel langage), forcement 1+1=0 alors que si on l'implémente avec des bytes, alors on aura 10. Il ne faut pas oublier la différence entre l'aspect conceptuel et son implémentation.

En fait cela m’amène a une réflexion sur les équivalences d'encodage et pourquoi utiliser l'un plutôt qu'une autre (on en revient a un problème de modélisation non?) Ainsi je résumerai la première partie de la vidéo de Bruce par:
zero       0    0
un          1    1
deux      2    10
trois       3    11
quatre    4    100
cinq       5    101
six         6    110 

C'est trois représentations sont équivalent des concepts mathématique associés (les valeurs de [0-6]) mais leur représentation syntaxique est différente et ne permettent pas les même choses car implémenter logiciellement une opération telle que l'addition sur un binaire sera plus évident que sur du décimal qui est plus simple que sur du lexical.... (d’ailleurs l'utilisation des porte logique le montre, faire quelque chose d’équivalent avec des "un" et des "deux" sera vraiment un challenge)

Mais on aurai aussi pu faire une représentation du type fonctionnel en utilisant les entiers de Peano [2]: au lieu d'encoder en binaire et de définir un opérateur tel que le +, avec Peano, on défini juste 0 comme point initial ( celui ci peut être définit comme l’équivalent de 0 mais on peut aussi le donner comme équivalent de 100 -> ceci s’appelle définir la sémantique mais c'est un autre problème et ça n'a d'importance que si on veut "traduire" la logique) et on définit l’opérateur SUCC représentant le suivant. Du coup pour faire comme dans le tableau précédent, on aura:

0  -> 0
1 -> SUCC(0)
2 -> SUCC(SUCC(0))
3 -> SUCC(SUCC(SUCC(0)))
4 -> SUCC(SUCC(SUCC(SUCC(0))
5 -> SUCC(SUCC(SUCC(SUCC(SUCC(0))

Avec ça on a aussi une représentation des entiers (ou encodage) n'utilisant qu'un seul symbole "0" et un opérateur...
Après si vous voulez rajouter des opérateur classique comme + alors il faut revoir implémentation qui la est fort simple car il suffit de combiner le nombre de SUCC de l'un avec l'autre (ou les concatener....)

Exemple:

SUCC(SUCC(0)) +SUCC(SUCC(0)) = SUCC(SUCC(SUCC(SUCC(0))

Bon je suis peut être parti un peu loin

Références:


[1] https://www.youtube.com/watch?v=i4jSXR4swrY&index=390&list=WL
[2] http://www.fil.univ-lille1.fr/~wegrzyno/portail/Elfe/Doc/TPPL3/tp3002.html

mercredi 10 janvier 2018

Les gens vivent en s'appuyant sur leurs convictions et leurs connaissances. Ils appellent ça la réalité.

Petit aparté sur une phrase que j’aime bien :

"Les gens vivent en s’appuyant sur leurs convictions et leurs connaissances. Et ils appellent ça la réalité. Mais connaissance et compréhension sont des concepts ambigus. Cette réalité n’est peut être qu’une illusion. Et si le monde n’était régi que par de fausses croyances… Ne porterions nous pas un autre regard sur la réalité ?"

J’aime bien cette phrase car elle met bien en évidence l'écart qui existe entre le monde et le réel, la connaissance que nous en avons et les croyances que nous portons sur lui.

C’est amusant car ces sujets sont traités par une chaine youtube très intéressante, Hygiène Mental ou c’est justement le propos de chercher à rationaliser notre rapport avec les réel, de ce que nous connaissons de lui et ce que nous pensons savoir mais qui ne se base en réalité que sur des croyances.

Cette chaine ne cherche pas à mettre croyances et connaissances en opposition mais cherche à leur donner à chacune une définition et un rôle dans le processus de réflexion intellectuelle.

Les connaissances sont des concepts et propositions évaluées, éprouvées et approuvées sur une base de faits à l’aide de méthodologies. Donc une connaissance est une affirmation démontrée, démontrable, fondée sur des connaissances valides.

Deux questions se posent donc: comment démontrer les premières connaissances? et qu’est ce qu’une méthode permettant de faire une démonstration?

Évidement il existe des connaissances que l’on ne démontrera pas car celle ci sont suffisamment élémentaire pour ne faire l’objet d’aucune contradiction. Ces connaissances font consensus comme “le nez au milieu de la figure”... et si l’on souhaite un jour pouvoir élaborer un raisonnement, il nous faut bien considérer des concepts comme acquis sans démonstration sans prendre le risque de tomber dans des paradoxes [2].

Maintenant que nous avons une base de faits, il nous faut être capable de les manipuler afin de nous permettre de tirer des conclusions. Pour cela, nous avons des propositions de base comme nous pourrions l’avoir en informatique avec la logique binaire. Ainsi, pour pouvoir raisonner et déduire des choses, il nous faut pouvoir associer des faits. En utilisant des opérateur comme ET, OU, NON ou -> (implique) nous allons pouvoir commencer à élaborer des déductions.

Sur cette base nous allons pouvoir élaborer nos premiers raisonnement nous permettant de construire une sorte de pyramide inversée de la connaissance. A partir d’une base étroite, on va déduire de nombreuses connaissances, nous permettant d'accéder à d’autres déductions et connaissances.

Bien sur ce qu’il y a de dangereux avec cette pyramide est que au plus une connaissance est en bas de l’échelle et au plus elle a de l’importance. Si elle est fausse, tout ce qui en suit est faux (même si cela semble plein de bon sens…. mais comme on dit le diable se cache dans les détails et c’est souvent en les négligeant que l’on tombe dans ses pièges) De la même manière, l’appareil de déduction se base sur des opérateurs nous permettant d'élaborer nos résultats, si ces opérateurs comportent des erreurs, alors rien dans nos déductions n’a de valeur.

Nous voyons ici que l’on peut considérer le réel comme un territoire dans lequel la connaissance cherche à s'étendre. Bien sur cette vision est absolue. Les gens ne partagent pas le même espace de connaissance et celle ci peut même parfois se coupler à ce que l’on peut considérer comme de la croyance.

Mais qu’est ce que l’on considère comme de la croyance? Alors avant de poursuivre, j'arrête tout de suite ceux qui vont se sentir attaquer, ici on ne traite pas de la pertinence de croire ou ne pas croire en un dieu ou autre chose car la croyance fait partie du réel. Aucun doute la dessus, puisque par définition, si une croyance a été même simplement pensée c’est qu’elle existe conceptuelle au moins. Alors nul doute que la croyance existe et l'objet de cette croyance également (en tout cas du moins pour celui qui croit). En fait, la croyance pourrait se définir par "ce qui se conçoit et qui est accepté comme vrai" (je ne précise pas sans preuve car si la croyance n'en a pas besoin, en apporter peut être un plus et permet à la croyance de devenir une connaissance, on serait dans un processus de démonstration).

Quel est alors la différence avec la connaissance? La différence est simple, la croyance n’a pas besoin d'être validé pour être accepté. Cependant à l’inverse de la connaissance, la véracité de la croyance n’est pas absolu. En effet, croire, c’est un choix, alors que face à la connaissance et sa démonstration (hormis si erreur il existe, ou si le cadre ne correspond pas l'utilisation de cette connaissance) nous ne pouvons la réfuter et si on le fait alors une démonstration doit elle aussi être produite.

Nous avons donc là une différence notoire. La croyance s’accepte ou se réfute sans preuve. La connaissance à l’inverse demande des preuves permettant sa validation et surtout permettant son invalidité (car il sera toujours plus convainquant de démontrer qu'une théorie est fausse plutôt que le contraire [8]). Toutes deux, croyances et connaissances, si elles se veulent une représentation du monde, ne peuvent être associé. Ainsi, il est absurde de demander de croire ou ne pas croire à une théorie sans l’avoir comprise et vu, tout comme il est absurde de vouloir une démonstration de l'existence de dieu.

Alors pourquoi cette opposition entre connaissances et croyances? Tout simplement parce que l’humain cherche à dominer et utilise la manipulation pour faire passer des croyances pour des connaissances. Ainsi, il n’y a aucun problème a croire en dieu tant que cette croyance n’est pas le support d’une démonstration. Beaucoup de scientifiques sont croyant. La ou un problème peut apparaitre, c’est lorsque l’on produit une pseudo démarche scientifique afin de crédibiliser un discours et des pseudo faits qui ne sont en fait que des croyances. Et c’est la qu'entre en jeu le point central de l'acquisition et la validation de la connaissance (et ici c'est effectivement en opposition avec la croyance) : la démarche intellectuelle, qui elle ne se concentre pas sur les faits mais la manière de les traiter [9].

Par exemple, et ça peut paraitre anodin aux yeux de tous mais actuellement nous avons un spot publicitaire de la FDJ portant sur la chance. En mettant en scène des célébrités sportives, elle tente de faire croire qu’il est possible de croire en la chance alors que ces gens sont tous sauf des chanceux. Leur travail et leur succès ne fait aucun doute et leur réussite, ils ne la doivent qu’a eux et le seul caractere assimilable a la chance qui peut intervenir dans leur vie est le caractère aléatoire de aléa de la vie (comme tout le monde d'ailleur on peut se faire renverser par une voiture au detour d'une rue) pas du tout la manière dont ils la vivent. Au delà de l’aspect moral de cette publicité (le jeu d’argent étant l’une des plus grosses addictions qui soient [3]), nous sommes face a typiquement un détournement de la démarche intellectuelle en substituant d’un côté la notion de chance (croire que l’on peut gagner qui est en fait très mais très très faible [10] ) avec un concept pseudo scientifique de chance dans lequel intervient un travail considérable (ces gens ne sont pas a ce niveau pour rien). Et encore nous parlons ici que du contenu mais dans la forme, on peut aussi largement dénoncer la démarche scientifique de prendre des cas isolés de réussite (que l'on peut assimiler a un argument d’autorité [11]) pour témoigner de leur chance (qui n’a rien à voir avec la chance aux jeux).

Ce sujet n’est pas le seul car nous avons ici a faire a un exemple classique de manipulation ou l’on manipule les faits, et on manipule le processus de déduction au profit d’une croyance (celui de gagner). Mais il existe des situation plus critique pour la connaissance elle même, en dehors de la réfutation scientifique (qui fait appel au processus de validation de la connaissance), on assiste à des manipulations dont le but est même de faire reculer la connaissance aux profits de croyances comme le cas de la théorie de l’évolution contre les créationnistes [5], ou de substitution de connaissance par d'autres mais fausse basé sur des faits et de démonstrations fallacieuses comme le conflit des platistes et des globeux [6] ou plus récemment le réchauffement climatique [7] ou l’on voit même de la récupération politique...

Sur le fond, il n’y a aucun problème a croire, tant que celle-ci ne cherche pas a se substituer à la connaissance. Au contraire, croire fait parti de l'imagination et c'est en cherchant a confronter nos croyances avec la réalité qu'avec un processus de démonstration on parvient à transformer parfois croyance en connaissance. Cette transformation doit être elle même rigoureuse et honnête en minimisant les biais en gardant a l'esprit que si on ne parvient pas a valider quelque chose, cela ne signifie pas qu'elle n'existe pas et qu'a l'inverse si l'on ne parvient pas a invalider quelques chose, cela ne signifie pas non plus qu'elle est vrai et il existe aussi des choses indémontrables.

Enfin attention avec la notion d'opinion (la votre ou celle d’un autre), elle ne vaut pas la connaissance mais relève de la croyance si elle n'est pas sourcé d'une référence qui a fait consensus. En effet, l'opinion est souvent un mélange des deux (connaissances et croyances) l'une et l'autre un peu mélangé dans l'esprit des gens quand elle n'est pas elle même fondé sur l'opinion d'un autre car comme on dit une opinion c’est comme les trou du *** ….. tout le monde en a un. ^^ Mais je vous invite vraiment a voir cette vidéo ou connaissances et croyances sont vraiment bien expliquées [1].

Références

[1] Hygiène mental : https://www.youtube.com/watch?v=09Fgix9yqbk
[2] Monsieur Phi : https://www.youtube.com/channel/UCqA8H22FwgBVcF3GJpp0MQw
[4] http://www.ifac-addictions.fr/l-addiction-aux-jeux-de-hasard-et-d-argent.html
[5] http://www.hominides.com/html/theories/theorie-evolution-idees-fausses.php
[6] http://www.leparisien.fr/sciences/le-retour-en-force-de-la-theorie-de-la-terre-plate-06-04-2017-6829746.php
[7] https://fr.wikipedia.org/wiki/Controverse_sur_le_r%C3%A9chauffement_climatique
[8] https://fr.wikipedia.org/wiki/Raisonnement_par_l%27absurde
[9] https://youtu.be/z8W8CygtlzQ
[10] http://www.spreadthetruth.fr/vous-avez-moins-de-chance-de-gagner-au-loto-que-de/
[11] https://fr.wikipedia.org/wiki/Argument_d%27autorit%C3%A9

lundi 8 janvier 2018

Jenkins Reverse Proxy Apache

Un petit article pour l'installation de Jenkins derrière un server Apache.

Si configurer le reverse proxy pour accéder a Jenkins n'est pas forcement un soucis [1] si l'on se borne a utiliser le protocole http, il ne sera pas toujours évident de faire de même avec https (http+ssl)

Sans rentrer dans le détail de ssl qui fera l'objet d'un autre article (génération des certificats pour apache), on prendra garde en plus de la configuration classique:
ProxyPass /jenkins http://localhost:8081/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8081/jenkins
De ne pas oublier l'ajout de la translation de protocole pour Jenkins:

RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
Voila, un article tres bref mais bon ce n'est peut qu'un detail pour vous mais pour nous ca veut dire beaucoup....

[1] https://wiki.jenkins.io/display/JENKINS/Running+Jenkins+behind+Apache


dimanche 7 janvier 2018

Maven, préparons des parents

Dans un précédent article [1], nous avions vu les principes généraux de Maven et son utilisation. Nous avions egalement vu le pattern parent/module/projet qui permet d’organiser la structure des projets.

Dans cet article, nous allons nous concentrer sur la partie haute de ce pattern en présentant une proposition de pom parents génériques ainsi que quelques déclinaisons de sous parents pour des sous classes d’applications (dans notre cas pour des application OSGI, des projets de plugins mavens et dans un avenir proche pour des application JEE)



Pour illustrer et expliquer ce pattern, je me permettrai de m'inspirer de mes propres projets de mes pom parents du dépôt Git Hub [2]

Nomenclature 

De façon générale, tous pom doit définir 4 points pour lesquels j’applique la nomenclature suivantes:
  • groupid = org.tc.${FONCTION}
  • artifactid = tc-${FONCTION}[-module]
  • version = [maj].[min].[ft]
  • packaging = pom
ou

  • $[FONCTION] est le rôle du pom courant 
  • [-module] la gestion du cas particulier du pom module
  • [maj] modification majeur du composant ( généralement fonctionnelle)
  • [min] modification mineur du composant ( généralement technique)
  • [ft] modification suite à un correctif 

Le groupId permet a maven de classer le pom, ainsi si l’on transpose cela a un répertoire, cela représente un chemin de répertoires dans lequel on trouvera tous les projets de ce type.
L'artifactId représente l’identifiant unique du pom dans la famille de pom classer sous le groupId.
La version permet de gérer les évolutions dans le temps et les dépendances des composants entre eux selon ces évolutions.

Le packaging permet à maven de connaitre la nature du composant qu’il aura à construire ainsi, un packaging pom est typiquement un pom parent ou module alors que jar, implique que l'exécution du pom produise une application java packager. (On aura aussi par exemple des packaging de type war, ejb, bundle ou ear… [3]

Optionnellement, les poms (et dans mon cas ils seront systématiquement définis) il est possible de donner une description au pom permettant de rentrer un peu plus dans le détail de son rôle et egalement de definir le name qui n’est que le nom simple du pom (“human readable”) tel qu’il sera affiché dans le reator du processus Maven (le resultat d’execution du build) il est donc important d’en choisir un lisible, simple et évident.

On choisira un name comme ci-dessous:
name = ${project.artifactId}-${project.version}

Pom parent


<groupId>org.tc.parent</groupId>
<artifactId>tc-parent</artifactId>
<name>${project.artifactId}-${project.version}</name>
<version>0.7.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>Pom parent des projets</description>

Le plus important dans le pattern parent/module/projet est, comme pour une hiérarchie de classe, l'élément le plus abstrait, celui de plus haut niveau c’est a dire le pom parent. Le pom parent a pour role de factoriser l’ensemble des informations concernant les composants participant à la construction de toutes les familles d’applications de nos projets.

De plus il participe également  à la définition d’information d’ordre plus générale comme l’identité du mainteneur du pom, les url permettant d'accéder au dépôt git ou au site web du projet. Pour ce genre d’informations je vous invite à consulter le pom en question, nous nous intéresserons aux premières composantes.

Donc pour proposer aux futur projet un environnement de production cohérent, le pom parent va définir le type d’encodage des sources:


<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>


Il peut aussi déclarer ou sera déployée la production produite par maven en définissant le distributionManagement qui poussera les jar et les pom dans par exemple un artifactory ou un nexus:


<distributionManagement>
    <snapshotRepository>
     <id>artifactory</id>
     <name>artifactory-snapshots</name>
     <!-- ${arti-url} defined in conf/settings.xml url d'artifactory-->
     <url>${arti-url}/artifactory/libs-snapshot-local</url>
    </snapshotRepository>
    <repository>
     <id>artifactory</id>
     <name>artifactory-releases</name>
     <!-- ${arti-url} defined in conf/settings.xml  url d'artifactory-->
     <url>${arti-url}/artifactory/libs-release-local</url>
    </repository>
    <site>
     <id>siteweb</id>
     <!-- defined in conf/settings.xml correspond au repertoire local ou sera déposé le contenu du build de la phase site-->
     <url>${local-siteweb-url}</url>
    </site>
</distributionManagement>


Dans le cas présent, on en a profité également pour définir ou sera déployé le site maven si la phase site est exécutée (variable ${local-siteweb-url}). A noter, que l’on utilise des variables directement dans le pom qui doivent avoir été défini dans le settings. Cette approche rend certe le pom non utilisable directement mais il procure l’avantage de permettre la pré-configuration des builds pour l’environnement dans lequel il va s'exécuter. Dans le settings pour pouvoir exécuter le build, il faudra affecter a ces variables les urls de artifactory et du site web.

On passe ensuite à la définition des outils de reporting a utiliser pour la génération du site web maven du projet.

Dans notre cas, nous employons


<reporting>
    <plugins>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-plugin-plugin</artifactId>
      <version>3.3</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-changelog-plugin</artifactId>
      <version>2.2</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>2.10</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-docck-plugin</artifactId>
      <version>1.0</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jxr-plugin</artifactId>
      <version>2.3</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-pmd-plugin</artifactId>
      <version>3.0.1</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-project-info-reports-plugin</artifactId>
      <version>2.6</version>
     </plugin>
     <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-report-plugin</artifactId>
      <version>2.18.1</version>
     </plugin>
    </plugins>
</reporting>


Dont les rôles sont [4] :

  • maven-plugin-plugin : Permet de generer la description d’un plugin maven
  • maven-changelog-plugin : Permet de generer le rapport changelog
  • maven-checkstyle-plugin : Permet de generer le rapport d’analyse de checkstyle (bonne pratique d’ecriture du code)
  • maven-docck-plugin : Permet de vérifier la documentation
  • maven-jxr-plugin : fourni un rapport des references croisées des sources java
  • maven-pmd-plugin : fournir un rapport d’analyse de code du code java
  • maven-project-info-reports-plugin : Permet de consolider dans un rapport les informations complémentaire contenu dans les pom
  • maven-surefire-report-plugin : permet de fournir un rapport d'exécution des tests unitaires

Ensuite par défaut il est possible de déclarer que tous les projets utilisent les même outils de tests. Dans le cas de nos projets nous avons fait le choix d’utiliser JUnit et Mockito


<dependencies>
    <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.10</version>
     <scope>test</scope>
    </dependency>
    <dependency>
     <groupId>org.mockito</groupId>
     <artifactId>mockito-all</artifactId>
     <version>1.9.5</version>
     <scope>test</scope>
    </dependency>
</dependencies>


Nous avons traité tous les éléments annexes au build lui même (c’est a dire la documentations et les informations complémentaires générées lors de la construction du site maven) . Maintenant, il convient de définir la configuration des builds eux même et donc la configuration des composants participants à ces builds. Ces éléments sont à déclarer entre les balises <build></build>.

Premier point a ajouter aux builds est la déclaration des répertoires de ressources et de les spécifier filtering. De cette façon, il est possible de déclarer des fichiers de configuration incluant des variables qui seront remplacées et affectées au moment du build par la valeur déclarée dans le pom. Ainsi, en déclarant des profils avec des valeurs différentes, il est possible de réaliser des productions incorporant des configurations differentes. (Nous reviendrons sur ce point plus tard, ce ne sont pas les exemples d’utilisations qui manquerons)


<resources>
 <resource>
  <directory>src/main/resources</directory>
  <filtering>true</filtering>
 </resource>
</resources>


Ensuite, il faut ajouter différents plugins:

Le plugin permettant de spécifier le JDK à employer ainsi que sa version:


<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.1</version>
 <configuration>
  <verbose>true</verbose>
  <source>1.8</source>
  <target>1.8</target>
  <testSource>1.8</testSource>
  <testTarget>1.8</testTarget>
  <arg>-XprintRounds -XprintProcessorInfo -Xlint -J-verbose</arg>
  <encoding>UTF-8</encoding>
  <fork>true</fork>
  <!-- defined in conf/settings.xml -->
  <executable>${JAVA_1_8_HOME}\bin\javac</executable>
 </configuration>
</plugin>


Les options -XprintRounds -XprintProcessorInfo -Xlint -J-verbose ont pour but d’augmenter la verbosité pendant la compilation et de fournir plus d’informations sur l’utilisation du processeur d’annotation [5].

Comme pour les urls dont nous avons parlé, il faudra ajouter la variable ${JAVA_1_8_HOME} à votre settings permettant à maven de savoir ou se trouve votre installation de Java.

Pour produire la javadoc on ajoutera le plugin suivant avec le paramètre Xdoclint:none afin a rendre le parseur générant la documentation moins rigide [6], (sinon il se peut que vous ne puissiez plus générer votre java doc):


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <version>2.9</version>
  <executions>
    <execution>
      <id>attach-javadocs</id>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <additionalparam>-Xdoclint:none</additionalparam>
      </configuration>
    </execution>
  </executions>
</plugin>


Même combat avec le plugin maven site qui va aussi vous produire la javadoc en plus des reporting que nous avons vu précédemment:


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-site-plugin</artifactId>
  <version>3.3</version>
  <configuration>
  <reportPlugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <configuration>
        <additionalparam>-Xdoclint:none</additionalparam>
      </configuration>
    </plugin>
   </reportPlugins>
   </configuration>
</plugin>


Enfin si vous livrer vos sources sous la forme d’un jar séparé de vos binaires, il faudra ajouter le plugin maven-source-plugin:

Pom parents fils

Voila on a fait le tour des plugins du pom parent principal. De la même manière, on va pouvoir créer d’autres pom parent plus spécialisés héritant de ce pom [2]. Sans entrer dans le détail, le dépôt propose par exemple de façon plus ou moins abouti des pom parent pour la production de bundles OSGI ou des plugins maven ou des ébauches pour la production de projets JEE ou Android.

Pom Module

Une fois ces pom définit, il reste à orchestrer leur production. Pour cela on utilisera un pom module.


<groupId>org.tc.module</groupId>
<artifactId>tc-parent-module</artifactId>
<name>${project.artifactId}-${project.version}</name>
<version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>Pom module de tc-project</description>


De façon très simple, un pom module ne définit que la liste des projets à construire.  Dans le cas de notre dépôt ce pom se constitue donc du pom parent principal et des pom fils au sein du balisage xml module:


<modules>
  <module>tc-parent</module>
  <module>tc-osgi-parent</module>
  <module>tc-jee-parent</module>
  <module>tc-maven-plugin-parent</module>
  <module>tc-android-parent</module>
</modules>


A noter que l’on retrouve souvent les pom parents et les pom modules sous la forme d’un seul et même pom. Si cette configuration est souvent la plus simple lorsque l’on a qu’un seul projet java a réaliser (même constitué par plusieurs sous projet), il n’est pas préconisé de procéder ainsi. En effet comme pour le pattern MVC ou l’on retrouve souvent le contrôleur et la vue implémenter dans le même composant, il est important pour éviter des rework de respecter la règles de la séparation des préoccupations. Ainsi, il sera plus simple de modifier la liste des éléments à construire sans avoir a modifier la version du pom parent et par voie de conséquence tous les pom en héritant.

Enfin dernier point à considérer selon les convenances, pour que le build puisse aboutir dans le cas d’utilisation de la phase deploy de maven, il est nécessaire de permettre au pom module d'être uploader dans un repository distant. Il reste alors a votre choix de soit declarer dans le pom un bloc distributionManagement comme nous l’avons fait pour le pom parent mais cela revient à dupliquer du code ou plus simplement, de déclarer le pom module comme fils du pom parent afin de bénéficier du distributionManagement hérité de celui ci.

Pour plus d’information sur la construction des pom je vous invite a consulter la documentation officielle [7]

References:

[1] https://un-est-tout-et-tout-est-un.blogspot.fr/2017/12/maven-introduction.html
[2] https://github.com/collonville-tom/tc-parent
[3] https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Packaging
[4] http://matthieu-lux.developpez.com/tutoriels/java/maven/?page=site
[5] http://www.javatronic.fr/articles/2014/08/31/how_to_make_sure_javac_is_using_a_specific_annotation_processor.html
[6] http://blog.joda.org/2014/02/turning-off-doclint-in-jdk-8-javadoc.html
[7] https://maven.apache.org/guides/introduction/introduction-to-the-pom.html

mercredi 3 janvier 2018

Bonne année 2018

Un article pas trop long pour vous souhaiter une bonne, belle et heureuse année 2018 et aussi pour faire une petite road map des articles en préparation.

Comme vous avez pu le voir; ces dernières semaines ont été un peu chargé et cela a ralenti le nombre d'articles, surtout que j'ai l'impression de plus me documenter que de produire (en terme de code ou de doc) du coup je ne publie qu'à la volée des choses sur lesquelles je tombe comme l'article des QQOQCCP ou sur les processus de dev ou quand je suis amener a faire des modifications dans ma prod perso (la je parle des deux sujets sur les dépôts et paquets Debian)

J'avais promis quelques articles comme Maven, la modélisation et l'IDM  (complété avec un article général sur UML) et c'est chose faite mais je ne suis pas parvenu a sortir ceux sur Drools ou Gradle. alors le second est passé complétement a la trappe car je voulais le faire a la suite de celui sur Maven pour lequel je prévois une suite... et pour le premier, et bien, bien que connaissant déjà Drools pour l'avoir utilisé régulièrement, j'ai voulu élargir le sujet au systèmes expert dans le but de nous amener a de futur article très intéressant portant sur l'Intelligence Artificiel. Cependant, la tache est conséquente et non seulement va nécessiter plusieurs articles mais demande aussi de réorganiser le plan.

Donc voila en résumé de ce début d'année je vous prépare les sujets suivant:
  • un peu d'IA en commençant par le système expert suivi par Drools
  • une suite pour Maven
  • Gradle comme alternative a Maven
  • et n'oublions pas les sujets JEE

Au passage j’espère que le petit écart en passant pas la theorie du control par supervision vous aura plus, j'ai pour projet de le compléter par un article sur les processus communicant et la vérification de modèle.

Voila une beau début d'année en perspective!