Journal
Ce journal contient 23 entrées.

Réparer npm lorsqu'il s'autodétruit
Si, pour une raison inconnue, npm s'autodétruit après une mise à jour globale (npm update -g), il peut s'agir d'un problème lié à une ancienne version.
Réinstallez node (par exemple: brew uninstall --force node && brew install node) puis réinstallez npm en utilisant la version de npm fournie avec node (npm install -g npm).
C'est un problème idiot, mais malheureusement fréquent: https://github.com/npm/npm/issues/4099

Réinstallez node (par exemple: brew uninstall --force node && brew install node) puis réinstallez npm en utilisant la version de npm fournie avec node (npm install -g npm).
C'est un problème idiot, mais malheureusement fréquent: https://github.com/npm/npm/issues/4099
GitHub - tdebatty/java-string-similarity: Implementation of various string similarity and distance algorithms: Levenshtein, Jaro-winkler, n-Gram, Q-Gr
Une librairie Java pour calculer des distances ou des scores de similarité entre des chaînes de caractères.
Algorithmes implémentés :
Levenshtein O(m*n)
Normalized Levenshtein O(m*n)
Weighted Levenshtein O(m*n)
Damerau-Levenshtein O(m*n)
Optimal String Alignment O(m*n)
Jaro-Winkler O(m*n)
Longest Common Subsequence O(m*n)
Metric Longest Common Subsequence O(m*n)
N-Gram O(m*n)
Q-Gram O(m+n)
Cosine similarity O(m+n)
Jaccard index O(m+n)
Sorensen-Dice coefficient O(m+n)

Algorithmes implémentés :
Levenshtein O(m*n)
Normalized Levenshtein O(m*n)
Weighted Levenshtein O(m*n)
Damerau-Levenshtein O(m*n)
Optimal String Alignment O(m*n)
Jaro-Winkler O(m*n)
Longest Common Subsequence O(m*n)
Metric Longest Common Subsequence O(m*n)
N-Gram O(m*n)
Q-Gram O(m+n)
Cosine similarity O(m+n)
Jaccard index O(m+n)
Sorensen-Dice coefficient O(m+n)
sorttable: Make all your tables sortable
sorttable, une petite librairie js pour ajouter des fonctions de tri à un tableau.
Java 8 Stream Tutorial - Benjamin Winterberg
Un gros tutoriel par l'exemple pour l'API Stream de Java 8. Dans cette API, un stream (flux) est une suite d'éléments sur laquelle des opérations successives vont être appliquées (map, reduce, filtre, tri, agrégation, etc.). À noter que les traitements sur le flux peuvent être parallélisées très facilement.
Le code est particulièrement élégant, du fait de l'approche fonctionnelle de l'API (https://fr.wikipedia.org/wiki/Programmation_fonctionnelle). Cela rappelle, par certains côtés, l'API LINQ de C#.
J'apprécie beaucoup que Java se dote de plus en plus de sucre syntaxique : les lambdas à la place des classes anonymes, les try with resources à la place des try/finally, les foreach à la place des itérateurs, les imports statiques, etc.
Au fil des évolutions, la critique comme quoi Java serait "trop objet", déjà plutôt idiote à l'origine*, devient parfaitement caduque. En effet Java peut être vu comme un langage multiparadigme :
- impératif, si l'on utilise des méthodes et des imports statiques
- objet, évidemment
- fonctionnel (à l'origine avec les classes anonymes et du bidouillage), grâce aux lambdas
Bien sûr, avec les librairies appropriées, d'autres approches sont possibles : programmation orientée aspects, programmation réactive, etc.
* Plutôt idiote car, indépendamment de tout langage, un paradigme de programmation est une manière d'écrire et de structurer des programmes. Un langage exploite les philosophies d'un ou de plusieurs paradigmes pour fournir des constructions syntaxiques qui simplifient l'écriture et la lecture du code pour un programmeur ayant décidé de penser conformément à ces philosophies. Rien n'empêche d'exploiter un langage et d'y écrire des programmes en se conformant à une philosophie différente. Le C est un exemple flagrant : impératif par nature, il est tellement permissif, que l'on peut y penser en objet, en fonctionnel, en réactif, etc.

Le code est particulièrement élégant, du fait de l'approche fonctionnelle de l'API (https://fr.wikipedia.org/wiki/Programmation_fonctionnelle). Cela rappelle, par certains côtés, l'API LINQ de C#.
J'apprécie beaucoup que Java se dote de plus en plus de sucre syntaxique : les lambdas à la place des classes anonymes, les try with resources à la place des try/finally, les foreach à la place des itérateurs, les imports statiques, etc.
Au fil des évolutions, la critique comme quoi Java serait "trop objet", déjà plutôt idiote à l'origine*, devient parfaitement caduque. En effet Java peut être vu comme un langage multiparadigme :
- impératif, si l'on utilise des méthodes et des imports statiques
- objet, évidemment
- fonctionnel (à l'origine avec les classes anonymes et du bidouillage), grâce aux lambdas
Bien sûr, avec les librairies appropriées, d'autres approches sont possibles : programmation orientée aspects, programmation réactive, etc.
* Plutôt idiote car, indépendamment de tout langage, un paradigme de programmation est une manière d'écrire et de structurer des programmes. Un langage exploite les philosophies d'un ou de plusieurs paradigmes pour fournir des constructions syntaxiques qui simplifient l'écriture et la lecture du code pour un programmeur ayant décidé de penser conformément à ces philosophies. Rien n'empêche d'exploiter un langage et d'y écrire des programmes en se conformant à une philosophie différente. Le C est un exemple flagrant : impératif par nature, il est tellement permissif, que l'on peut y penser en objet, en fonctionnel, en réactif, etc.
square/javapoet · GitHub
Une API pour générer du code Java. Plutôt pratique pour compléter Recoder, dont j'avais parlé il y a longtemps : http://benjaminbillet.fr/news/index.php?link=d5gw1l
Par exemple, le code suivant :
MethodSpec main = MethodSpec.methodBuilder("main")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(void.class)
.addParameter(String[].class, "args")
.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
.build();
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(main)
.build();
JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build();
javaFile.writeTo(System.out);
Génère le code Java suivant :
package com.example.helloworld;
public final class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, JavaPoet!");
}
}
Par exemple, le code suivant :
MethodSpec main = MethodSpec.methodBuilder("main")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(void.class)
.addParameter(String[].class, "args")
.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
.build();
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(main)
.build();
JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
.build();
javaFile.writeTo(System.out);
Génère le code Java suivant :
package com.example.helloworld;
public final class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, JavaPoet!");
}
}
Java for Everything
Les critiques récurrentes envers Java sont, la plupart du temps, infondées. Celle de la verbosité est particulièrement absurde, le concept d'autocomplétion est plus vieux que moi. On retrouve aussi le grand débat "bytecode interprété vs. code compilé", qui n'intéresse que ceux qui ignorent l'existence des mécanismes de compilation à la volée. Java est un langage qui évolue depuis sa création, aussi bien au niveau de sa syntaxe (p. ex. l'opérateur diamant, le multicatch, le try-with-resource, les lambda) que de son SDK (p. ex. NIO, streams, gestion de la concurrence), mais il continue à être jugé sous le prisme de ses premières versions.
Globalement, et cela est vrai pour tout langage, les critiques portent soit (i) sur la façon dont les logiciels sont implémentés en utilisant le langage, soit (ii) sur des points de détail plus ou moins significatifs. Ce sont ces détails qui permettront, justement, de déterminer le meilleur langage en fonction des besoins.
La question "quel est votre langage de programmation préféré" est particulièrement intéressante. Apprendre un langage, c'est assez facile, mais maîtriser son écosystème (librairies, techniques avancées, environnements d'exécution, compilateurs, débogueurs, etc.) est un exercice long et complexe. D'où des développeurs qui vont finalement toujours utiliser leurs langages/outils préférés dans n'importe quelle situation et inventer des arguments abracadabrantesques pour justifier leurs choix (ou invalider celui des autres).
A la vérité, je n'ai pas encore trouvé un "bon" langage, tous ceux que j'ai essayé et que j'utilise au quotidien sont tout juste "potables". A un moment donné ou à un autre, tous ces langages m'ont agacés pour tel ou tel problème de syntaxe, de logique, de performance ou d'incomplétude. Le langage idéal, à mon sens, est celui qui permet de décrire rapidement les idées (concrètes) que l'on cherche à implémenter sans forcément avoir à gérer les limitations propres aux structures du langage, à ses primitives, à ses librairies et à son environnement. Peut être y a t'il de l'espoir dans les domain-specific language, du fait de leur spécialisation.

Globalement, et cela est vrai pour tout langage, les critiques portent soit (i) sur la façon dont les logiciels sont implémentés en utilisant le langage, soit (ii) sur des points de détail plus ou moins significatifs. Ce sont ces détails qui permettront, justement, de déterminer le meilleur langage en fonction des besoins.
La question "quel est votre langage de programmation préféré" est particulièrement intéressante. Apprendre un langage, c'est assez facile, mais maîtriser son écosystème (librairies, techniques avancées, environnements d'exécution, compilateurs, débogueurs, etc.) est un exercice long et complexe. D'où des développeurs qui vont finalement toujours utiliser leurs langages/outils préférés dans n'importe quelle situation et inventer des arguments abracadabrantesques pour justifier leurs choix (ou invalider celui des autres).
A la vérité, je n'ai pas encore trouvé un "bon" langage, tous ceux que j'ai essayé et que j'utilise au quotidien sont tout juste "potables". A un moment donné ou à un autre, tous ces langages m'ont agacés pour tel ou tel problème de syntaxe, de logique, de performance ou d'incomplétude. Le langage idéal, à mon sens, est celui qui permet de décrire rapidement les idées (concrètes) que l'on cherche à implémenter sans forcément avoir à gérer les limitations propres aux structures du langage, à ses primitives, à ses librairies et à son environnement. Peut être y a t'il de l'espoir dans les domain-specific language, du fait de leur spécialisation.
java-design-patterns/ at master · iluwatar/java-design-patterns · GitHub
Les différents design patterns du GoF, en Java. Les modèles UML s'appliquent, en principe, à n'importe quel langage.
Le livre original : http://www.amazon.com/Design-Patterns-Object-Oriented-Professional-Computing/dp/0201634988

Le livre original : http://www.amazon.com/Design-Patterns-Object-Oriented-Professional-Computing/dp/0201634988
Getting Started with Java® SE Embedded on the Raspberry Pi
Java SE Embedded est une version allégée de Java SE, conçue pour tourner avec des processeurs ARM v5/6/7, 32Mo de RAM et 10-50Mo de ROM/Flash/disque (dépend du profil utilisé, c'est-à-dire des sous-ensembles de l'API Java SE utilisés par l'application).
C'est plutôt léger, ça tourne uniquement sous UNIX/Linux et c'est vraiment du Java 8, contrairement à cette abomination de Java ME.
Idéal, donc, pour faire du Java sur un Raspberry PI.

C'est plutôt léger, ça tourne uniquement sous UNIX/Linux et c'est vraiment du Java 8, contrairement à cette abomination de Java ME.
Idéal, donc, pour faire du Java sur un Raspberry PI.
Tessel
Un microcontrôleur qui exécute du JavaScript, il fallait oser. Outre ce choix discutable, Tessel possède les caractéristiques suivantes :
- 180mhz ARM Cortex-M3 LPC1830
- 32mb SDRAM
- 32mb Flash
- TI CC3000 WiFi radio
- 20-pin GPIO bank for general prototyping
Il peut aussi embarquer des modules vendus séparément, comme des capteurs (accéléromètre, capteurs de température, de bruit, d'humidité et de luminosité), des interfaces de communication (bluetooth, 2G, etc.), un GPS, un lecteur RFID ou encore un appareil photo.
Il ne possède cependant pas de batterie embarquée, mais peut être alimenté avec une batterie USB.

- 180mhz ARM Cortex-M3 LPC1830
- 32mb SDRAM
- 32mb Flash
- TI CC3000 WiFi radio
- 20-pin GPIO bank for general prototyping
Il peut aussi embarquer des modules vendus séparément, comme des capteurs (accéléromètre, capteurs de température, de bruit, d'humidité et de luminosité), des interfaces de communication (bluetooth, 2G, etc.), un GPS, un lecteur RFID ou encore un appareil photo.
Il ne possède cependant pas de batterie embarquée, mais peut être alimenté avec une batterie USB.
Import Limits on Cryptographic Algorithms
Java est limité dans la taille des clés AES (128 bits) sous prétexte que certains pays interdisent certaines tailles de clés. La solution ? Télécharger la "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy" et la copier dans le dossier lib/security du JRE de l'utilisateur.
...
C'est IDIOT. Pourquoi quelque chose d'aussi banal que des clés AES 256 nécessiterait des manipulations de la part de l'utilisateur ? C'est une limite (absurde) à la diffusion des applications.
La seule bonne solution aurait été de faire l'inverse ; autoriser les clés de n'importe quelle taille par défaut et laisser ensuite les développeurs gérer les restrictions (stupides) des pays dans lesquels l'application est diffusée.
Ou mieux tiens, si ces pays veulent faire des lois (idiotes), ils n'ont qu'à se débrouiller pour diffuser eux-même une version restreinte du JRE.
...
C'est IDIOT. Pourquoi quelque chose d'aussi banal que des clés AES 256 nécessiterait des manipulations de la part de l'utilisateur ? C'est une limite (absurde) à la diffusion des applications.
La seule bonne solution aurait été de faire l'inverse ; autoriser les clés de n'importe quelle taille par défaut et laisser ensuite les développeurs gérer les restrictions (stupides) des pays dans lesquels l'application est diffusée.
Ou mieux tiens, si ces pays veulent faire des lois (idiotes), ils n'ont qu'à se débrouiller pour diffuser eux-même une version restreinte du JRE.
Java Magic. Part 4: sun.misc.Unsafe - mishadoff thoughts
Un petit tour d'horizon de sun.misc.Unsafe, une classe qui encapsule les opérations de manipulation de la mémoire (entre autres) que l'on retrouve sous n'importe quel OS, et qui servent notamment de base à l'implémentation des constructions plus "safe" fournie par le langage (concurrence, etc.).
Il y a des petites astuces intéressantes toutefois, pour ceux qui aiment bidouiller.
Il y a des petites astuces intéressantes toutefois, pour ceux qui aiment bidouiller.
The Java EE 7 Tutorial:Java API for WebSocket
Les WebSocket (RFC 6455) sont des canaux bidirectionnels ouverts entre un navigateur et un serveur web en réutilisant la socket TCP d'une connexion HTTP.
En pratique cela permet de simplifier l'écriture des applications Webs qui nécessitent de récupérer des évènements depuis un serveur.
Cela permet notamment de se passer des techniques de polling jusqu'alors massivement utilisées.
A noter qu'il ne faut pas confondre les WebSocket et WebRTC, qui désigne un ensemble de protocoles et d'API permettant à des navigateurs de communiquer en pair-à-pair. WebRTC est encore cependant à l'état de brouillon au W3C et à l'IETF même si Chrome, Firefox et Opera ont déjà intégrés des implémentations.

En pratique cela permet de simplifier l'écriture des applications Webs qui nécessitent de récupérer des évènements depuis un serveur.
Cela permet notamment de se passer des techniques de polling jusqu'alors massivement utilisées.
A noter qu'il ne faut pas confondre les WebSocket et WebRTC, qui désigne un ensemble de protocoles et d'API permettant à des navigateurs de communiquer en pair-à-pair. WebRTC est encore cependant à l'état de brouillon au W3C et à l'IETF même si Chrome, Firefox et Opera ont déjà intégrés des implémentations.
Protéger des pages web par mot de passe dans Tomcat
J'ai été confronté à ce problème récemment, et cette page de la documentation passe en revue les moyens pour indiquer à Tomcat comment se connecter à une "base de données" (ici appelé "realm") contenant des noms d'utilisateurs, des rôles et des mots de passe.
Cette base de données peut être une véritable base de donnée accessible par JDBC, un simple fichier XML ou un annuaire.
Il convient ensuite, dans le web.xml des applications web, de définir quels utilisateurs/rôles peuvent accéder à quelles pages : http://docs.oracle.com/javaee/5/tutorial/doc/bncav.html
Depuis Java EE 6 ce procédé peut se faire directement en utilisant des annotations : http://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html

Cette base de données peut être une véritable base de donnée accessible par JDBC, un simple fichier XML ou un annuaire.
Il convient ensuite, dans le web.xml des applications web, de définir quels utilisateurs/rôles peuvent accéder à quelles pages : http://docs.oracle.com/javaee/5/tutorial/doc/bncav.html
Depuis Java EE 6 ce procédé peut se faire directement en utilisant des annotations : http://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html
High Level Concurrency Objects
En référence à http://benjaminbillet.fr/news/index.php?link=d5gw5, il semble aussi que les nouvelles API de programmation concurrente soient en général méconnue des développeurs Java formés il y a quelques années.
Java a introduit, toujours depuis Java 5, des structures pour simplifier la gestion de la concurrence dans une application.
La documentation d'Oracle est très claire sur le sujet :
- Les pools automatiques : http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
- Le framework Fork/Join : http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
- Les collections concurrentes : http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html
- Et de véritables verrous : http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
Java a introduit, toujours depuis Java 5, des structures pour simplifier la gestion de la concurrence dans une application.
La documentation d'Oracle est très claire sur le sujet :
- Les pools automatiques : http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
- Le framework Fork/Join : http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
- Les collections concurrentes : http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html
- Et de véritables verrous : http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
Java NIO: Introduction
J'animais une formation face à des ingénieurs quand je me suis rendu compte que peu de gens connaissent les méthodes moderne pour faire du réseau en Java. La plupart des gens connaissent assez bien l'API de manipulation de flux réseau avec les socket stream, mais pas du tout la "nouvelle" (depuis Java 5 quand même) API "New IO" (NIO).
NIO permet notamment de communiquer en réseau de manière asynchrone (ce qui simplifie l'implémentation de nombreuses applications) en utilisant des canaux et des buffers.
Et justement, ce tutoriel décrit très bien l'API.
NIO permet notamment de communiquer en réseau de manière asynchrone (ce qui simplifie l'implémentation de nombreuses applications) en utilisant des canaux et des buffers.
Et justement, ce tutoriel décrit très bien l'API.
D3.js - Data-Driven Documents
D3.js (Data-Driven Documents) est une bibliothèque graphique JavaScript qui permet d'afficher des données sous forme graphique. C'est une librairie très populaire et très simple d'utilisation, à consommer sans modération.
Native equivalents of jQuery functions
jQuery est une librairie géniale, notamment grâce à sa couche d'abstraction qui simplifie GRANDEMENT la compatibilité entre les navigateurs.
Toutefois, tout comme HTML/CSS, Javascript évolue et ses fonctionnalités de manipulation du DOM commencent à être majoritairement supportées par les navigateurs.
Aussi, quand ce n'est pas nécessaire, remplacez jQuery ou prototype par Vanilla JS http://vanilla-js.com/
(blague à part, Vanilla JS c'est juste le nom hype du Javascript nu).

Toutefois, tout comme HTML/CSS, Javascript évolue et ses fonctionnalités de manipulation du DOM commencent à être majoritairement supportées par les navigateurs.
Aussi, quand ce n'est pas nécessaire, remplacez jQuery ou prototype par Vanilla JS http://vanilla-js.com/
(blague à part, Vanilla JS c'est juste le nom hype du Javascript nu).
SIGAR API (System Information Gatherer and Reporter)
Une librairie très intéressante pour manipuler des informations systèmes (processus, informations sur le matériel, consommation des ressources, etc.) en Java.
Recoder
Encore un outil Java. Oui je sais, c'est le troisième en deux jours, mais en ce moment je bosse beaucoup sur Java et Android. Promis, après j'arrête un moment <<
Bref, Recoder est un parser très complet qui, à partir de code source ou de bytecode Java, est capable de construire un arbre syntaxique abstrait (AST). Cet AST peut être modifié à loisir et, détail fort intéressant, transformé à nouveau en code source.
Le support de Java 7 est en cours.
Bref, Recoder est un parser très complet qui, à partir de code source ou de bytecode Java, est capable de construire un arbre syntaxique abstrait (AST). Cet AST peut être modifié à loisir et, détail fort intéressant, transformé à nouveau en code source.
Le support de Java 7 est en cours.
Javassist
Javassist est une librairie d'instrumentation de code très puissante, permettant d'intégrer directement de nouvelles méthodes, classes, etc. directement dans des binaires java.

Ce journal est basé sur Ginger, un gestionnaire de lien minimaliste développé dans le cadre d'un stage de perfectionnement. Pour plus d'informations, consulter le wiki consacré à mes projets personnels.