Java 9, tu modules ?

Rémi ?

Vous connaissez Rémi ? Il est maître de conférences à Marne la Vallée, développeur d’ASM (j’ignorais ça), d’OpenJDK, expert pour le JCP (et clairement spécialiste des évolutions du langage, pas la partie JavaEE) où il a ajouté invokedynamic, et a travaillé sur les lambda, Jigsaw.

Java 9

Java 9 est la dernière grosse release, parce que c’est pénible. Ca va être remplacé par une release tous les six mois …​ c’est un peu plus rapide. Et donc, dans six mois, on verra var apparaître dans le langage Java.

Les modules

Historiquement, ça devait arriver en Java 6 ou 7 …​ Ca a pris un peu de retard.

Qui veut modulariser le JDK ?

Il y a d’une part des développeurs du JDK qui veulent le faire évoluer, mais ne peuvent pas à cause de toutes les APIs qui utilisent des classes « cachées » du JDK. Et d’autre part …​ des experts de sécurité qui considèrent les failles de la plateforme.

D’autres problèmes

L’enfer du CLASSPATH

Sans outil pour gérer automatiquement le CLASSPATH (genre maven, gradle et autres), c’est l’enfer. Par ailleurs, quand le ClassLoader charge une classe, il scanne linéairement tous les jars et charge la première classe qu’il trouve. Du coup, c’est long. Mais aussi super merdique quand on a deux versions du même artefact. Du coup, on aimerait bien que ce soit géré par la JVM. De la même manière, éviter que les NoClassDefFoundError ne sortent qu’à l’exécution serait une bonne idée pour les développeurs.

Alléger Java

Ce serait sympa de pouvoir faire tourner le code Java sur des plateformes plus légères (typiquement pour l’IoT). Personellement, ça meparaît vaguement possible avec des outils comme ProGuard de limiter la taille des dépendances, mais ce serait mieux d’avoir ça directement dans le JDK. Par exemple, rt.jar contient encore des parseurs XML (qui n’ont pas à être des classes privilégiées) ou CORBA (qui s’en sert encore ?).

Comment modulariser ?

standards

Aucun rapport avec Java, bien sûr

Il y a déja des standards de modules en Java

  • maven
  • gradle
  • JBoss
  • OSGi
  • JavaEE

Du coup, Jigsaw doit fournir un système de modules compatible avec tous ces systèmes prééexistants. Ce qui implique tristement qu’il ne peuvent pas contenir de numéros de version. Et ça, c’est moche.

Modularisons donc !

C’est quoi un module ?

Dans un module, il y a

  • des dépendances
  • et des classes qu’on veut garder invisibles aux autres packages

Par exemple, java se est constitué d’un paquet de modules …​ dont java.compiler. Ce qui signifie qu’il n’y a plus de distinctions JRE/JDK.

Tout ça est décrit dans un module-info.java qui va être compilé comme le reste du code. Ca empêche les modifications ultérieures, ce qui est bien.
A la compilation, il ne peut donc plus y avoir de « split-packages » (des packages déclarés dans deux JARS), ou de dépendances cycliques.

Qu’est-ce qu’on perd ?
  • les « split-package »
  • setAccessible(true) sur une classe d’un module fermé

Au passage, ça permettra enfin à Rémi d’optimiser les champs final (un truc dont j’étais sûr qu’il existait déja pourtant)

Enfin, sauf si on active le flag --illegal-access=permit (qui est parfaitement clair). Notez qu’il y a d’autres valeurs possibles (warn, debug). Bon, un jour, il disparaîtra.

En bonus, les classes JavaEE cachés dans JavaSE (java.xml.bind, java.xml.ws et autres) ne seront plus dans le JDK. Notez que ces classes sont toujours accessibles via des dépendances Maven.
Les classes sun. et com.sun. qui ne sont pas utilisées sont également supprimées.

A noter : L’annotation @ForRemovall (je ne suis pas sûr de l’orthographe) indique les classes qui seront supprimées dans la prochaine version du JDK. C’est une version étendue du classique @Deprecated.

Comment trouver les dépendances

Avec jdeps, par exemple, on peut facilement trouver toutes les dépendances d’un module. Notez que cet outil existe déja dans Java8.

Oui, mais comment je transforme mon application pour Java9 ?

Pour ça, Rémi a développé son application de test : ModuleTools qui lui permet de lire et d’écrire un fichier module-info.java ou module-info.class.Et dans son application, il déclare quelques modules, qui dépendent tous de java.base (comme les classes Java dépendent de java.lang.Object).

Contrairement à maven, un require de module n’est pas transitif (contrairement à maven). Du coup, il y a un require transitif, mais qui est limité à un niveau.

En terme d’organisation de fichiers, il est possible d’avoir plusieurs organisations, dont par exemple plusieurs modules dans le même dossier (ce qui n’est supporté ni par maven, ni par gradle, ni par les IDE).

Il est possible de stocker la version du JAR dans le module-info, et de la réutiliser depuis le code, mais le système de modules n’utilise pas la version.

Comment utiliser un JAR non modulaire ?

Typiquement, une dépendance de Maven Central.On ne peut évidement pas ajouter simplement le JAR dans le CLASSPATH. Il suffit en fait de mettre le jar dans le module-path, et Java va générer automatiquement un module-info, qui permet en plus à ce module automatique de dépendre de JARs du CLASSPATH.Et comment s’appelle ce module ? Soit le nom fourni dans le MANIFEST.MF comme Automatic-Module-Name, soit le nom du JAR sans le numéro de version. Du coup, en ce moment, sur GitHub, c’est la fête à l’Automatic-Module-Name. Au passage, il est possible d’utiliser les JARs modulaires comme des JARs classiques, en les mettant dans le CLASSPATH !

Comment limiter la visibilité ?

Si on veut faire un module interne, il est possible de limiter sa visibilité à certains modules spécifiques, et pas au monde entier. C’est très chouette pour mieux gérer la sécurité. C’est ce qu’ont fait les développeurs du JDK pour la tristement célèbre sun.misc.Unsafe dont une partie a été déplacée dans jdk.unsupported, et une autre partie dans un jdk.internal.misc. Du coup, la réflexion n’est plus possible sur les champs privés (dommage pour gaedo). C’aurait été pénible pour JPA …​ mais les fournisseurs d’implémentation JPA utilisent des agents qui changent le code avant son exécution. Cela dit, la réflexion reste possible grâce à open sur un package ou sur le module.Par ailleurs, le très moche ServiceLoader a été étendu pour fonctionner avec les modules …​ La différence, c’est que la description est un peu propre et intégrée au module-info. Et la description à la fois des fournisseurs d’implémentation et de l’utilisation de ces implémentations doit être fournie. C’est super cool, parce que ça permet de tester les injections de dépendances.

Packager ?

Avec jlink, on peut créer une image à la volée de l’application et de ses dépendances. Pratique pour l’embarqué, évidement, mais aussi pour Docker. Hélas, il ne peut pas y avoir de modules automatiques, parce qu’avec ces modules automatiques, il faut embarquer tout le JDK, et ça limite en plus énormément les possibilités d’optimisation de jlink. C’est un peu la carotte de Jigsaw. Ca permet aussi d’utiliser une JVM minimale de 3 Mo !. Bon, sans JIT, mais sur un Raspberry, c’est pas vraiment utile. Ca permet aussi de garantir la durée d’exécution …​ avec jaotc, qui génère du code natif (qui pourra même se passer de JIT). Le but à terme de cette expérience est (accrochez-vous) de réécrire la JVM en Java (pour se débarasser du code C++).

Evidement jlink (et l’ahead-of-time-compiling) est chouette pour les performances. Et pour l’espace disque.

Conclusion

Modulariser, ça n’est pas si facile, à la fois pour les implémenteurs et les utilisateurs. A ce sujet, la conclusion de Rémi est parfaitement claire : si vous avez une application non-modulaire, n’essayez pas de la modulariser. C’est à la fois long, complexe, et sans valeur ajoutée. En revanche, si vous vous lancez dans une nouvelle application, la modulariser dès le départ peut être utile.

Et merci à nos amis du chtijug pour une soirée sans faille, dans une super salle, et avec une vue vraiment chouette !

Publicités

Comment est-ce que je gère mes services avec Rancher et Consul ?

Mais pourquoi je veux faire ça ?

Admettons que je veuille me mettre aux microservices … ou plutôt aux services packagés dans des conteneurs docker (quelquesoit la taille des dits services).

Je commence par les packager dans des conteneurs Docker et c’est « cool ». Parce que comme ça, je n’ai pas besoin de demander à l’admin sys de déployer du Java partout, mais du Docker.

Donc, j’ai mes services et mon admin a entendu parler (sans doute sur ce blog) d’un chouette truc qui s’appelle Rancher. Et très vite, il veut ajouter une base de données de configuration (parce que mettre les fichiers de config dans les conteneurs, c’est pas terrible … lisez donc 12 factors apps à ce sujet). Donc il me dit d’utiliser Consul. Et Consul, c’est bien pour la config, mais ça fait aussi service registry. C’est-à-dire que ça permet à un service d’en trouver un autre dynamiquement. Un peu comme du JNDI pour les Javaistes … ou du LDAP pour les ancêtres.

Le problème, c’est que Consul fait service registry, et pas service discovery. C’est-à-dire qu’il peut stocker les services, mais pas découvrir quand ils démarrent ou s’arrêtent (enfin pour l’arrêt, si, mais bon, par symétrie, on va considérer ici que ça n’est pas son boulot).

Et comment je fais pour enregistrer mes services ?

Donc, il faut ajouter un composant d’enregistrement, un « registrator ». Coup de bol, il y en a deux pour Rancher :

  1. Gliderlabs registrator
  2. Rancher Registrator

Pourquoi y en a-t-il deux ? C’est assez bien expliqué dans cette chouette question : Do you kill registrator ? Notez que l’auteur de la question est également l’auteur du second registrator … ceci expliquant cela.

Et ça marche comment ?

D’abord, je vous montre le docker-compose.yml, et ensuite on en discute, ok ?

Dans ce fichier, il y a quelques trucs à noter

Attention à la version !

registrator ne supporte l’option useIpFromLabel que dans la branche master. En ancien développeur Java appréciateur des beaux numéros de version, ça me fait mal, mais bon, on me dit que ça marche comme ça dans le monde de Docker …

internal ?

Ca permet à registrator d’utiliser les ports effectivement exposés par les images, au lieu d’utiliser les ports visiobles hors de Rancher, donc ne l’oubliez pas

cleanup, deregister et resync

La doc de registrator est assez claire, mais ça vaut le coup de bien préciser que ces options sont là pour garantir qu’il n’y a pas de services n’existant que dans Consul (ce qui est un peu bête)

useIpFromLabel

A partir de Rancher 1.2, Rancher utilise un système nommé CNI, ce qui fait que l’ip et le port ne sont plus accessibles via le conteneur Docker mais via le label (ajouté dynamiquement par Rancher) io.rancher.container.ip. Du coup, il faut bien signaler au registrator qu’il faut utiliser ce label pour lire l’adresse du conteneur.

Attention aux labels !

Parce que ce registrator est déployé dans Rancher. Il faut donc qu’il soit présent sur tous les hosts (puisqu’il lit la liste des conteneurs depuius le démon Docker local) (d’où le io.rancher.scheduler.global). Il faut également qu’il ait accès au DNS (d’où le io.rancher.container.dns). Les autres options sont moins indispensables.

Et paf !

Une fois que ces opérations sont effectuées, vos conteneurs seront automatiquement enregistrés dans Consul au démarrage, et supprimés de Consul lorsqu’ils s’arrêtent).

Mais qu’est-ce que vous avez fait de Javascript ?

Note préliminaire : cet article est avant tout un recueil de mes opinions. Il ne s’agit pas de faits, ou d’éléments soigneusement étudiés, mais plus d’irritations, d’incompréhensions. (Vu que cet article est en train de devenir mon plus lu, je préfère baliser le terrain)

Je viens de finir un bon paquet de développement Javascript « full-stack » avec Nodejs, Vuejs et tout un tas de trucs. Et franchement,

(oui, il va y avoir un paquet de tweets, parce que j’ai eu l’occasion d’en parler)

Mais qu’est-ce que vous avez fait au langage ?

a7fc014bf8488b37d60ed7dc6c76acbff5d3fb7491ff3cbd302a4a9a4743ef14Quand je faisais du Javascript, avant, on avait un chouette langage fonctionnel salement déguisé en Java par le biais d’un marketting stupide. Et un jour, V8 est arrivé, et comme l’héritage par prototype, c’est pas cool, ES5 et ES6 se sont succédés à un train d’enfer pour apporter toutes les folies des langages orientées objet : import, héritage, interfaces, closures, théoriquement, vous avez maintenant tout ça.

Le cas particulier de l’import

Ca marche comment l’import ? En Javascript classique, ça marche facilement avec requirejs (la doc est claire, et le besoin assez simple). Avec ça, écrire une application un peu complexe, c’est quand même raisonnablement facile (je le sais, je l’ai fait). Mais en ES6, si vous êtes côté serveur (dans Nodejs, kwa), vous écrivez

const expect = require('expect.js')

Mais côté client, vous écrivez

import localForage from 'localforage'

Mais c’est vraiment génial, cette idée de NE PAS UTILISER LA MEME SYNTAXE DANS DIFFERENTS ENVIRONNEMENTS ! Je ne sais pas combien de langages précédents ont eu cette idée … douteuse. Tout ce que je sais, c’est que je n’en connais aucun.

Non mais static, c’est static ou bien ?

Oui, parce que bon, superposer les concepts Java/C# sur une base Lisp, ça donne parfois des résultats curieux.

Du coup, quand vous créez une classe comme ça

class CaVaMarcher {
	static uneFonction() {
	}
	
	static uneAutre() {
		this.uneFonction()
	}
}

Est-ce que ça marche ? Eh bien je n’en sais rien. Mon code me dit que oui, mais ma tête me dit que non. PARCE QUE STATIC AVEC THIIS C’EST ENCORE UNE IDEE GENIALE ! A la décharge des fous qui ont créé ES5/ES6, this a toujours été un problème du Javascript.

Mais qu’est-ce que vous avez fait au build ?

Parce que bon, jusqu’à node/npm, livrer un projet JS, c’était pas super dur : tu prends tes fichiers, si tu es audacieux tu les minifie (mais en vrai ça n’est pas si important si tu caches bien ton JS, ou que tu utilises un CDN), tu les mets dans ton WEB-INF/resources (en Java), et BAM, c’est servi.

Webpack de l’enfer

escapefromhellgraphicEn 2017, comme tu fais de l’ES6, mais que ton navigateur ne le supporte pas forcément, tu passes par webpack pour le transformer en honnête Javascript.

Et dans quel enfer tu t’enfonces ? A côté de ça, générer les interfaces des EJB 1.0 avec ejbgen c’était de la rigolade. Que je vous raconte. Le truc génère un gros fichier Javascript (5 Mo pour notre application) à partir du paquet de code, d’images, de CSS (compilé depuis des préprocesseurs, parce que franchement, la syntaxe CSS n’est pas terriblement lisible – qu’ils disent). Pour ça, il faut configurer ça avec un fichier webpack.js à la syntaxe … Tellement merdique. Regardez donc cet exemple. C’est un cas vraiment super simple qui ne fait pas grand chose de sophistiqué. Et pourtant, c’est déja la merde non documentée. Alors quand il faut ajouter des trucs comme vuejs (j’en reparlerai, pas de panique), ça devient incroyablement tordu.

Surtout avec les histoires de sourcemap (qui sont un authentique exemple de complexité accidentelle) qui sont loin de marcher aussi bien qu’imaginé.

Du coup, webpack, ça marche, mais franchement, ça a un côté terrifiant de complexité inutile dans le concept et dans l’implémentation. Heureusement, le reste du build cache ça.

Non mais ce build JS

npm de merde

dessin-de-merdeLà ça m’énerve vraiment. Quand ces folies de build ES5/ES6 ont commencé, et que les besoins de gérer un cycle de vie et des dépendances se sont posés, il me semble que les Javascripteurs auraient pu, à défaut d’utiliser, tout au moins copier les idées de maven, par exemple, ou d’autres build tools du monde Java (ou d’autres, mais je ne les connais pas). Parce que franchement, les mecs qui ont créé npm (qui a fourni le format canonique du package.json) ne se sont pas trop fait chier : une liste de dépendances, et une map associant des noms de commandes, et c’est marre. Pareil pour la récupération des dépendances : les mettre dans un dossier node_modules dans le projet, sans trop se soucier de la version téléchargée, c’est une PUTAIN D’IDEE DE MERDE.

Yarn de super-merde

800px-kin_no_unkoA cause des défauts invraissemblables de npm, les mecs de facebook ont créé yarn qui « ccorige le problème des versions incorrectes ». PUTAIN MAIS ILS NE POUVAIENT PAS ETRE AMBITIEUX ? Parce que bon, d’accord, ces histoires de dépendances incertaines, c’est un problème. Mais il y en a d’autres.

Comme par exemple le fait que les commandes soient dans cette saleté de map, et soient en fait des exécutables système (qui doivent donc être dans le PATH, et ne marchent donc pas sous Windows – gg les gars).

Ou comme le fait qu’il n’y ait aucune espèce de build standard, et qu’il faut donc tout réécrire dans chaque projet.

Ou comme le fait qu’il ne soit pas possible de définir de modèle de projet, ou de modularisation du build.

Franchement, yarn, c’est bien de l’esbrouffe.

Et ces frameworks de merde

wrong-tool-pizzaParce que bon, angular, c’est l’horreur, tout le monde le sait, ça a été conçu par des mecs qui avaient trop fait de développement JavaEE et en avaient perdu l’esprit. React, je peux pas en dire du mal (mis à part le fait que si tu t’en sers sans la surcouche de Redux, t’as l’air d’être dans la merde, puisque tout le monde te dit qu’il faut utiliser Redux).

Du coup, forcément, tu suis tout le monde comme un mouton, et tu prends vuejs avec l’impression d’être un putain de révolutionnaire. Bon, c’est dommage pour toi, parce que Ractivejs, c’est comme vuejs, mais en mieux (si si, en mieux).

D’abord, t’as pas le concept complètement con de fichier .vue dans lequel tu mélanges le HTML, le Javascript, et le CSS. Parce que qu’est-ce que vous avez PUTAIN DE PAS COMPRIS DANS LA SEPARATION DES RESPONSABILITES ? Je veux dire, quand t’écris ton composant, tu passes pas ton temps à modifier les trois en même temps, si ? En bonus, le fichier .vue, ben ton navigateur ne le comprend pas. Du coup, tu dois aller modifier ton webpack.config.js qui était déja bien merdique pour utiliser le vue-loader, qui fout un peu la merde avec le sass-loader. Bon, mais ce problème de build n’est en fait qu’un épiphénomène.

Ben oui, parce que vuejs fournit peut-être des « composants », mais il faut encore que tu utilises un framework CSS, sinon tu vas galérer avec les resets CSS. Du coup, tu te rajoutes Bulma (oui, le nom est merdique pour les recherches dans Google) par exemple, mais tu dois aussi l’intégrer dans webpack parce qu’il est fourni en SCSS (re-argh).

Et bien sûr, c’est quand tu ajoutes Bulma, vuejs, et toutes tes dépendances, que ton fichier JS généré atteint les 5 Mo. 5 Mo, tout ça parce que tu ne veux pas que l’utilisateur attende au démarrage de ta page. Non mais qu’est-ce que c’est que cette merde ? Tout ça pour un PUTAIN DE SITE MOBILE. Comment vous croyez que ça peut marcher avec une connexion un peu faible ? Ben mal. Très mal. Trop mal.

Et ce offline de merde

pas-de-signal-panneLà, pour le coup, c’est chaud, mais je veux bien comprendre le concept. Quand ton navigateur est déconnecté, pour pouvoir utiliser l’application web, tu dois stocker toutes tes données dans le cache local.

Mais là, tu fais comment ? Tu utilises localForage directement ? Ou tu passes par des web workers ? Et là, j’atteinds ma limite, donc je ne peux pas râler en majuscules.

Mais pour tout le reste, clairement, le monde Javascript déconne à pleins tubes. J’espère bien que ça changera, parce que là, c’est super pour que les sociétés de service fourguent des consultants qui connaissent juste le framework à la mode. Mais honnêtement, c’est pas comme ça qu’on produit du logiciel durable. Mais est-ce que ça fait partie des besoins des clients ? Je n’en sais rien.

Mais du coup tu vas refuser de faire du Javascript ?

Non, parce que dans les bonnes conditions (donc sans node, sans webpack, sans framework aux idées à la con), développer une appli web Javascript (par exemple avec requirejs, Ractivejs, et un peu d’axios pour les requêtes Ajax, le tout en Javascript classique) est assez plaisant, et surtout très simple. Par contre, les outils actuels du développeur full stack Javascript sont, à mon sens, à la fois insuffisants et conceptuellement incorrects.

Je vais me retrousser les manches

Comme tous les ans, en rentrant de vacances, j’ai commencé à trier nos superbes photos des châteaux de la Loire.

Donc paf, je lance GeoSetter (dont l’intégration Google Maps ne marche plus depuis un moment), j’intègre tous mes fichiers GPX, puis j’ouvre Microsoft Expression Media pour saisir les tags IPTC complémentaires … Et l’intégration avec Bing Maps ne marche plus non plus ! Oui, bon, ça fait déja deux logiciels. Dont aucun n’est à jour ni ne fonctionne parfaitement. Surtout que je renomme ensuite les photos avec XNView ! Et là, vous vous rendez bien compte que c’est n’importe quoi. Et je ne vais pas vous parler du fait que j’ai le même genre de workflow pour la musique.

Et comme je suis en ce moment dans une dynamique de création, de nouveauté, d’innovation, de découverte, et que je veux me lancer dans JavaFX, Gradle, Kotlin, et la programmation réactive, et que je cherchais un thème … eh ben c’est tout trouvé !

Donc, d’abord, je crée le projet sur Framagit.

Ensuite, je me forme un peu à Kotlin (et à Gradle, mais ça a l’air plus simple – pour l’instant).

Et après, à partir d’un peu d’étude d’iPhoto, de Microsoft Expression Media, de Daminion Tools, je me lance dans le développement de Yapo.

Oui, parce que j’aurais pu reprendre le nom d’un projet sur le même thème que j’avais précédement lancé (jPhotoOrganizer), mais j*, ça fait un peu naze comme nom, et je ne voulais pas reprendre d’existant (surtout que l’existant, en l’occurence, est caché … dans Google Code – RIP).

Mais à mon avis, pour l’instant, je vais avoir des ambitions modestes : faire une espèce d’explorateur de fichier avec des actions supplémentaires pour les images …

Les jeux de l’été 2017

Cet article est en quelque sorte une suite d’un article homonyme : les jeux de l’été.

Et comme le précédent, il liste les jeux auxquels nous avons joué.

Evidement, les précédents demeurent : Piña Pirata et Munchkin se tiennent en bonne forme. Mobile Frame Zero a été abandonné (beaucoup trop compliqué pour nos joueurs). En revanche, nous avons ajouté une extension à Munchkin : Ton destin est scellé. Ca ne change pas follement le jeu, mais ça ajoute quelques éléments bien marrants (j’ai particulièrement aimé les montures, les serviteurs sont quant à eux plus anecdotiques de mon point de vue).

Mais nous avons également ajouté à la ludothèque l’excellent Carcassonne, qui est vraiment chouette. Les règles sont simples, mais leur intersection crée des situations délicieusement tordues, où on peut facilement avoir l’impression de gagner la partie alors qu’un concurrent a posé quelques paysans habiles qui vont retourner le sort en sa faveur au décompte des points. Aussi sympathique que rempli de rebondissements.

Codingame : fin de partie

Il y avait ces dix derniers jours un contest codingame.

Et j’étais assez bien parti, puisque je suis arrivé en ligue silver. Malheureusement, à un moment donné, je me suis rendu compte que j’y passais sans doute trop de temps.

J’ai donc décidé d’arrêter de participer aux contests codingame. D’ailleurs, je ne pense pas me remettre à codingame, même en-dehors des contests, avant un bon moment. Je retire de nombreuses choses de mes participations que je vais tenter de découper en plusieurs morceaux

Wondev Woman

Sur le contest proprement dit, c’était bien. J’avais commencé à coder mardi un algorithme conceptuellement proche de celui que j’utilisais pour Hypersonic, me permettant théoriquement de faire une analyse complète du plateau à plusieurs tours d’avance. J’achoppais sur un problème de chargement des directions possibles, mais j’avais en tête une solution.

Mais avant un peu de vocabulaire

  • J’appelle action une action complète (MOVE&BUILD ou PUSH&BUILD).
  • Un mouvement est un élément d’une action (déplacer la case « active » dans le futur d’une des directions possibles). Donc si on y réfléchit bien, une action est une paire de mouvements. Petite révélation : la différence entre PUSH&BUILD et MOVE&BUILD est que, dans le premier cas, le premier mouvement arrive sur une case occupée

Du coup, mon algorithme devenait quelque chose ressemblant à

  1. Calculer les mouvements possibles au tour courant pour mes pions
  2. Pour chaque mouvement, calculer l’état du terrain après le mouvement (sans tenir compte de la position des joueurs). Il va y avoir des tonnes de superposition, qui correspondent à des futurs communs, ça offre une bonne réduction de l’espace de recherche.
  3. Scorer les positions des pions. Pour les meilleures positions, recommencer à l’étape 1. Le score utilisé doit être indépendant de la longueur des chemins

A mon avis, avec ça, j’aurais pu atteindre l’or. mais.

  • Implémenter un tel code est long, et assez fastidieux.
  • J’ai eu cette idée uniquement parce que j’ai repris hypersonic après la fin du contest
  • Je n’ai ni la motivation, ni le talent pour atteindre la légende (mon meilleur score à été d’atteindre le fond de la ligue gold).

Plus généralement

Ces constats, qui ne sont pas d’ordre techniques mais personnels, sont reproductibles pour tous les problèmes de codingame : il y a de bien meilleurs joueurs que moi, et je le vois clairement.

A mon avis, c’est parfait pour découvrir un nouveau langage. Et en réalité, attaquer ces problèmes en Java était pour moi une facilité. En théorie, j’aurais dû les attaquer en Python, en Scala, ou dans n’importe quel langage dans lequel j’ai envie de progresser vite.

Parce que les structures de données que j’ai mis en place, contrairement à d’autres participants, faisaient la part belle aux design patterns, à la bonne programmation orientée objet, bref au code Java bien idiomatique. Et je sais que j’aurais fait pareil dans d’autres langages.

Du coup, je vais arrêter d’y jouer en Java, et je m’y remettrais si je dois découvrir un nouveau langage.

Chtijug et barbecue

Gravitee

Bon, je connais les speakers depuis …​ 10 ans facile. Et ça fait plaisir de les voir sur scène !

Gravitee, un API Manager

Donc l’API management (voir la session chez Kiabi – et la page Wikipedia de définition), ça permet de créer et de publier des API, de les maintenir en état de marche, et enfin de collecter des statistiques d’usage.

D’un point de vue architecture, il y a principalement deux composants

  1. Un portail d’API, permettant l’enregistrement d’utilisateurs, la découverte des API.
  2. Une gateway, qui va exécuter les appels en les dispatchant auprès des services backend.

Pour les clients, ça peut être

  • Une façon d’exposer une API
  • Un reverse proxy
  • Un ESB pour les API REST (mais ça c’est faux : il y a tout un tas de différences entre l’API manager et l’ESB)

Gravitee, le produit

Existe depuis 2015, et nos speakers ont créé la société GraviteeSource pour fournir le conseil, la formation autour du produit.

Démonstration de création d’API

A partir d’un serveur exposant l’API, on peut facilement créer les éléments dans Gravitee grâce …​ à un wizard ! Il faut noter que, dans le wizard simple, la notion de plan de consomation (pour pouvoir facturer facilement, évidement). Par ailleurs, on peut importer facilement de la doc RAML/SWAGGER/Markdown. Et c’est fini, l’API est déployable

Consomation d’API

Une fois l’API créée, il faut créer une souscription pour pouvoir l’utiliser.

Et là, les petits gars, vous avez déja de quoi remplir quelques rapports de bugs pour améliorer vos présentations 😉

Cela dit, les écrans d’administration sont sacrément bien fichus, avec une vision complète des temps de réponse et de la qualité des réponses.

Réécriture de la réponse

L’un des éléments intéressants d’un API manager, c’est la possibilité de modifier les requêtes pendant leur exécution grâce à des politiques de transformation préconçues (des transformations simples) ou …​ du Groovy (j’aime beaucoup), ou aussi de créer un cache au niveau de la gateway.

Développement de policy

Comme gravitee est développé en Java avec des mécanismes de plugins typiques, ajouter une policy, c’est assez facile, et c’est parti …​ avec un archétype Maven ! Et je dois dire que le code produit par la génération d’archétype est, un peu comme pour Wisdom, assez complet.

Web multi-écrans

J’ai déja vu la présentation sur Youtube, mais en live, ça n’est évidement pas pareil …​

Un truc marrant dès le début de la présentation : Hubert nous parle de 2008 et de ses deux écrans. De mémoire, avec mon voisin de derrière, en 2009, on bossait dans une boîte où chaque poste avait 3 écrans sur deux machines avec Synergy …​ Et encore, ça n’était pas ma première fois avec plusieurs écrans.

Donc, plusieurs écrans, et des interfaces avec plusieurs écrans. Dans le web.

Un truc très intéressant dans sa présentation, c’est qu’il intègre un avis contraire, celui de quelqu’un qui affirme ne travailler qu’avec un seul écran.

Et Hubert enchaîne ensuite avec les différentes techniques permettant la communication : window.open, et autres hacks. J’ai malheureusement un trou dans mes notes. Dans mes souvenirs, il y a un ou deux hacks, et une technologie parfaite pour les applis du futur, mais pas forcément disponible partout.

Cela dit, il y a une faille dans cette présentation (formellement impressionante) : le cas d’usage est quand même super limité : faire du web, sur plusieurs écrans, sans serveur …​ mis à part TiddliWiki, je connais peu de projets sur ce créneau. D’ailleurs, même les applications comme Atom, Brackets, Code ont un serveur web (oui, dans le même process, mais conceptuellement, il y a quand même un client, et un serveur). Personnellement, quand j’ai le genre de besoin dont Hubert parle (avoir des clients qui communiquent entre eux), je reste simple et je mets du websocket sur mon serveur.

Conclusion

Les sujets étaient assez spécifiques, mais les speakers étaient très chouettes, et la soirée s’est finie tranquillement sur les pelouses de Norsys

Générer mon asciidoc dans docker

Non mais pourquoi je veux faire ça ?

Parce que j’ai des collègues qui n’ont pas installé Graphviz. Personnellement, je ne comprend vraiment pas pourquoi. Mais bon, chacun ses choix.

Donc, comme ils n’ont pas Graphviz, et ne veulent pas l’installer, qu’en bonus ils ne veulent installer ni maven, ni java, et qu’ils semblent considérer que Docker est « la meilleure chose depuis le pain en tranches » (un indice : à mon avis, c’est faux), j’ai créé une image docker « kivabien » :

Donc vous prenez ce dockerfile, là, et comme je n’aime pas trop l’idée de publier ça sur le Hub (faut voir aussi que je suis un peu une quiche en docker), ben vous le lancez … avec docker-compose et cette configuration :

d’un habile coup de docker-compose up. Et si tout se passe bien, vous allez retrouver votre dossier target votre doc correctement générée. Notez que, normalement, votre doc pourra contenir du PlantUML, des liens, toute la richesse d’asciidoc.

Elle est pas belle la vie ? Perso, je suis pas sûr, mais on me dit que c’est ça le progrès. Moi je dis ok.

 

Et pouf, un nouveau projet open-source !

Bon, le projet existe depuis un moment, et est déja utilisé par quelques happy fews.

Il s’agit de codingame-maven-plugins, qui fournit des plugins facilitant le développement et le déploiement pour Codingame.

Le source est chez framagit, parce que je me voyais mal faire un projet en com.github, et que Sonatype tient à ce qu’on détienne le domaine correspondant au groupId.

Du coup, merci framagit, et merci framasoft !

Hop, hop, hop, un chtijug !

Un nouveau site (les terrains de Décathlon), pour deux présentations …​ au chaud !

Dix méthodes pour garder les développeurs

J’ai vu les slides de cette présentation, j’en ai donc une idée assez précise (malheureusement, je n’arrive pas à les retrouver dans la timeline de Cyril …​).

Les 3/4 des développeurs sont plus on moins à la recherche d’un nouvel emploi.

Bien recruter

D’abord, il faut s’arranger pour que le recrutement se passe bien, avec un peu de transparence : vision, cadre, salaire, code, soft skills (beuark, quelle frangliche dilbertien), tout ça doit être présenté.

En bonus, il y a certaines pratiques à éviter :

  • L’offre d’emploi impossible
  • Le code sur tableau blanc, remplacé par exemple par Codingame (mais ça n’est pas encore le vrai environnement …​)

Et d’autres à favoriser

  • Code review
  • Pair programming (eh, mais c’est ce que j’ai fait avec Youssef !)

Proposer une carrière

Oui, alors ça, bon, je connais. Et franchement, les développeurs non motivés, au bout de 3 ans, ils sont devenus chefs de projet.

Quant au graphique produit par N. Martignole sur la carrière d’un déveeloppeur, il est adapté à la vision moderne de l’informatique. Expert au bout de 5 ans, c’est vraiment de la blague.

Travailler sur l’environnement

Avant tout, arrêter l’open-space. Et c’est vrai que mes expériences récentes, dans des bureaux de moins de 15 personnes, m’ont réconcilié avec les gens : quelqu’un qui vient me voir vient réellement me voir, et ça change tout, à la fois en qualité de communication et en amour-propre.

En parallèle, avoir des machines de qualité, et avec de bons écrans, c’est évidement bénéfique. Et de la même manière, avoir de bons logiciels, ça ne coûte pas bien cher par rapport à la valeur ajoutée.

Hey, mais ils citent le test de Joël ! Cool. Bon, en fait, je suis sûr que ce test reprend tout le contenu de cette présentation, mais je ne vais pas râler.

Organiser son travail

Mettre en place des features teams, ça peut être bien. Ou les pizzas teams. En tout cas éviter les équipes façon galère de 50 personnes.

Software craftmanship

Bon, je vous encourage à relire le manifeste …​

Du coup, pour ça, il faut avant tout vouloir s’améliorer. En passant, pour vouloir s’améliorer, il faut avoir un sens du temps long …​ Autrement dit, envisager sa vie professionnelle sur plus de deux ans …​ voire plus de dix.

Tech radar

Bon, là, j’ avoue, j’ai soupiré. Mettre en place un tech radar, ça a un côté tellement poussiéreux, tellement pénible. J’ai vraiment du mal à voir en quoi ça peut présenter un intérêt, parce que ça met en place des comités théodule internes. Je comprend le besoin d’urbanisme, mais franchement, j’ai l’impression que c’est la très mauvaise méthode pour suivre l’évolution technologique.

Ne pas se mentir

Dire qu’on est cool, avec des consoles, du café gratuit, des nerfs (eh, mais on a tout ça, et en plus une Wii U), ça ne vaut pas le travail intéressant (mais on a aussi ça, ça va).

Autrement dit, il ne faut pas remplacer le sens de l’entreprise par tout un tas de bonu qui, eux, ne font pas sens. Cela dit, c’est raccord avec le premier point : lorsqu’on recrute un développeur, on l’intègre au sens de l’entreprise, à ses valeurs.

S’organiser en communautés

Alors théoriquement, c’est censé permettre de la transversalité, encore faut-il que les communautés soient vivantes. Et pour ça, il leur faut des moyens matériels : du temps, de l’espace, des outils de collaboration.

Malheureusement, dans le seul contexte où j’ai vu des gens essayer, ça n’a rien apporté.

Contribuer à l’open-source

Bon, alors là, ça tombe bien, parce que ce matin, un collègue a lancé un recensement des participations de l’entreprise à l’open-source. Et ce soir, il y a déja 60 contributions recensées ! Evidement, parfois, c’est difficile, parce que la sécurfité, tout ça. Dans ces cas-là, monter un Gitlab est une très chouette idée.

Participer aux événements

brown bag lunch, conférences, jugs (ou meetups, ça dépend comment vous voulez appeler ça), tout ça, c’est assez plaisant effectivement. Et puis ça permet à des speakers débutants de prendre l’habitude de parler en public.

Conclusion

Je crois que le message est bon. Mais je crois aussi que le public n’est pas le bon : faire cette conf à l’USI, ou dans un truc de décideurs, bien sûr. Mais je ne suis pas sûr de l’intérêt pour les développeurs.

Vert.x et Kubernetes

Eh, mais c’est Clément Escoffier ! Sans vouloir dire de mal de Cyril et Romain, j’étais surtout venu voir Vert.x et des conteneurs, et je n’ai pas été déçu. Donc Clément va développer des microservices Vert.x et les déployer dans un cloud …​ local (parce que le wifi ne semble pas très bien marcher). Le tout sans aucun slide.

Et il va packager son application avec le vert.x-maven-plugin pour générer des fat-jars. Ca n’est pas indispensable, mais c’est plus facile. Et ça permet à Clément de montrer un peu de maven-fu (parce qu’honnêtement, il en a sacrément, du maven-fu).

Donc en Java, un vert.x, c’est une sous-classe de AbstractVerticle …​ mais ça marche aussi dans la plupart des langages supportés par la JVM (Scala, Groovy, Ruby, Clojure sans doute, …​). Et dans une application Vert.x, pour chaque requête, on appelle la méthode de réponse …​ dans le même thread. Et c’est cool, parce qu’il n’y a pas de context switch.

Mais d’un autre côté, il ne faut pas bloquer ce thread. Sinon c’est la merde.

Pour continuer à développer, avec vertx-web, on peut créer un routeur, et assigner à chaque route une méthode correspondante. Ensuite, Clément nous implémente le serveur tranquillement, avec un mode d’écriture qui m’a beaucoup amusé, et qui est à mon avis la marque des développeurs expérimentés.Par contre, IntelliJ IDEA qui s’amuse à mettre le nom du paramètre en gris devant la valeur, ça me trouble un peu, même si je dois bien reconnaitre que c’est une sacrément bonne idée.

Et maintenant, comment déployer ça sur le cloud ? Et en particulier Kubernetes ? Et en particulier OpenShift ? Donc Kubernetes, ça permet de gérer facilement des gros paquets de conteneurs (logs, sécurité, volumes, …​). Et avec OpenShift, on a une interface, et c’est cool. Et en bonus, on a du build automatisé, ce qui est encore plus pratique. Et avec tout ça, en tant que dév, Clément va pousser son code, qui sera buildé et déployé par OpenShift, et les requêtes seront exécutées dessus.

Et quand ça marche, ça fournit des trucs assez spectaculaires, comme par exemple du déploiement avec rolling updates ! Ou par exemple le déploiement de nouveaux pods avec un simple click. Du coup, comment partager les données ? Avec Redis, par exemple. Et évidement, il faut du service discovery …​ qui est vraiment très facile à implémenter avec vertx.

Et maintenant, depuis notre service, on va en appeler un autre …​ en parallèle …​ à travers RxJava ! Et d’un coup, l’une des propriétés intéressantes de http prend tout son sens : comme c’est un protocole chunked, il n’est pas éncessaire de calculer toute la réponse avant de l’envoyer. Du coup, la mémoire est moins utilisée, l’application coûte moins cher. Et en bonus, le garbage collector n’a pas besoin d’arrêter l’application pour passer. Et ça, c’est vraiment beaucoup plus efficace.

Et c’est le petit moment gênant où la démo s’enraye…​ Mais elle revient sur les rails assez rapidement.

Et maintenant, Clément ajoute des circuit breakers, au cas où le pricer soit un peu trop lent. Et là aussi, comme on fait du vertx, il faut un circuit breaker qui n’utilise pas de threads (donc pas hystrix, par exemple).

Et pour finir la démo, Clément pousse le code sur GitHub en live !

Conclusion

Le talk est à la fois parfaitement spectaculaire dans la forme et vraiment intéressant dans le fond : Vertx permet de développer très facilement des services HTTP (oui, on peut faire autre chose, mais à quoi bon ?), et l’intégration avec OpenShift était aussi poussée que propre.