Surprise avec le JDK 8 update 20

Cela fait maintenant quelques temps que j’utilise le Java 8, et je ne peux plus me passer de ses nouveautés : lambdas, streams, etc.

Mais aujourd’hui, en voulant tester la dernière mise à jour d’Oracle (update 20), j’ai eu une surprise : un code qui jusque là fonctionnait sans problème ne compile plus.

Voici un code simplifié illustrant le problème :

1
2
3
4
5
6
7
8
9
public static <T> T firstNonNull(T first, T second) {
  return first != null ? first : second;
}
 
public static Set<String> getStrings() {
 return new HashSet<>();
}
 
public static Set<String> doesNotCompileWithUpdate20 = firstNonNull(getStrings(), new HashSet<>());

Ce code compile sans difficultés avec toutes les versions précédentes du JDK 8 (release initiale, update 5, update 11). Mais après la dernière mise à jour, il n’arrive plus à inférer le type du dernier « new HashSet<>()« . Pour que le code compile à nouveau, il faut expliciter le type que le JDK n’arrive plus à inférer à partir du contexte :

1
public static Set<String> compile = firstNonNull(getStrings(), new HashSet<String>());

Si vous avez une explication à ce phénomène (autre qu’un bug dans la dernière release), merci de m’éclairer. J’ai ouvert une question à ce sujet sur StackOverflow.

Publié dans Java | Marqué avec | Laisser un commentaire

Installer Gitorious avec RVM

Introduction

Il y a quelques temps, je me suis lancé dans l’installation de Gitorious. Celle-ci n’est pas évidente (mais je ne suis pas très familier des déploiements d’applications Ruby on Rails).

Heureusement, pour palier à cette complexité, il existe un certain nombre de ressources pour aider. Voici donc une liste de liens qui m’ont aidé :

  • Sur Bitnami, il est possible de se procurer des images « prêtes à l’emploi », dont Gitorious (parfaites pour tester le programme, mais qui ne sont pas recommandées pour la production).
  • Des recettes Chef sont disponibles, pour automatiser l’installation.
  • Sur le site officiel, plusieurs guides d’installation en fonction de l’environnement.

En particulier, ce tutoriel est beaucoup plus simple que la version originale. C’est donc à partir de cet article que j’ai monté mon installation de Gitorious, avec quelques adaptations, que je me propose de partager ici, en espérant qu’elles aideront ceux qui veulent se lancer dans l’installation de Gitorious.

Rapidement, voici les modifications que je présenterai ici :

  • L’installation a été réalisée sur une Ubuntu Server 12.04 LTS.
  • Au lieu d’utiliser les paquets natifs, tout ce qui touche à Ruby sera géré par RVM, qui offre l’avantage de permettre de combiner comme on le souhaite plusieurs versions de Ruby et de gems, sans être limité par les versions disponibles dans le gestionnaire de paquets.
  • Les répertoires d’installations ne sont pas ceux du tutoriel.

Avertissement avant d’aller plus loin : n’étant ni développeur Ruby, ni administrateur système, il est possible que certains choix d’installation ou de configuration que je vais présenter ne soient pas recommandés. Dans ce cas, je vous remercierai d’apporter des précisions en commentaires.

Continuer la lecture

Publié dans Systèmes d'information | Marqué avec , , , | Laisser un commentaire

Compte-rendu heuristique du Paris JUG

Ce mardi soir avait lieu la soirée « Serveurs d’application » au Paris JUG. Après avoir pendant un temps pris mes notes en markdown (avec Mou), j’ai voulu tester la prise de note en carte heuristique. J’ai pour cela utilisé le logiciel XMind, que j’ai trouvé excellent pour cela.

Sans plus attendre, voici donc le résultat de ce test (zoomez ou téléchargez l’image pour voir ce que ça donne) :

Soirée Serveurs d'application

Soirée Serveurs d’application

Publié dans Java | Marqué avec , , | Laisser un commentaire

Maven au pays des proxys

Le problème…

Il y a quelques temps, j’ai eu pour mission de stabiliser et de « mavenizer » une application legacy, dont le build était devenu ingérable (dépendances dans divers répertoires, mélanges de scripts shell, Ant,  etc.).

Au sujet de la mavenization elle-même, je vous recommande cet article, donnant une méthode fiable permettant de retrouver la version exacte des dépendances lorsqu’elles ne sont pas connues. Je passe cependant rapidement sur cette étape qui n’est pas le sujet ici. Nous arrivons donc directement au moment où nous avons un fichier « pom.xml » convenable, dont nous voulons vérifier le bon fonctionnement pour assurer le packaging de l’application. Et c’est là que les choses commencent à se compliquer.

Car ce que j’ai oublier de préciser, c’est que cette mission est effectuée pour « Gros client », chez qui les règles de sécurité sont strictes : l’accès internet se fait uniquement au travers d’un proxy. Et plus particulièrement le modèle PALC avec toutes les options : identification individuelle obligatoire sur ledit proxy, mot de passe à modifier tous les 3 mois, verrouillage du compte après 5 tentatives ratées, etc. Pour Maven qui aime bien « télécharger l’univers », c’est problématique.

Petite digression sur une mauvaise surprise découverte lors de cette mission… Ubuntu 11.10 n’est pas du tout adapté au travail dans un environnement utilisant un proxy : il souffre en effet d’une régression empêchant le paramétrage d’exceptions (pour les serveurs du réseau local).

Paramétrer le proxy pour Maven

Maven fournit un guide pour paramétrer un proxy. L’opération consiste à renseigner les paramètres du proxy dans le « settings.xml » :

1
2
3
4
5
6
7
8
9
10
11
<proxies>
  <proxy>
    <active>true</active>
    <protocol>http</protocol>
    <host>palc.grosclient.com</host>
    <port>8080</port>
    <username>user</username>
    <password>password</password>
    <nonProxyHosts></nonProxyHosts>
  </proxy>
</proxies>

Une fois ce paramétrage effectué, les dépôts sont bien résolus et les dépendances téléchargées. Mais il reste un soucis : certains dépôts irréductibles résistent encore… Par exemple le dépôt JBoss, ou encore Sonatype OSS. La cause est vite identifiée : ces dépôts utilisent le protocole « https » et non « http ».

Qu’à cela ne tienne : on duplique le bloc « proxy » en modifiant le protocole. A ceci près que ça ne marche pas… Maven ne sait utiliser qu’un seul proxy à la fois. Si on utilise le proxy « https », on pert le « http », et inversement. Peut-être une idée de correction à implémenter pour le hackergarten de mercredi prochain

La seule solution que j’ai pu trouver à ce jour est de paramétrer les proxys au niveau de la ligne de commande :

1
2
3
4
5
6
7
8
9
10
mvn
  -Dhttp.proxyHost=palc.grosclient.com
  -Dhttp.proxyPort=8080
  -Dhttp.proxyUser=user
  -Dhttp.proxyPassword=password
  -Dhttps.proxyHost=palc.grosclient.com
  -Dhttps.proxyPort=8080
  -Dhttps.proxyUser=user
  -Dhttps.proxyPassword=password
  install

Il est possible de paramétrer un proxy dans le « settings.xml » et le deuxième en ligne de commande mais ce n’est pas très intuitif. J’aime autant que tous les paramètres soient au même endroit.

Une fois les paramètres correctement configurés, on peut les pérenniser en les enregistrant dans la variable d’environnement MAVEN_OPTS.

Utiliser un dépôt Maven interne

Suite au paramétrage correct des proxys (http et https), Maven peut à nouveau télécharger tout internet… et le build peut fonctionner. Nous pouvons donc aller plus loin et installer un dépôt Maven chez « Gros client », afin d’y publier les artefacts produits.

Cependant, ce serveur peut également servir à régler autrement notre problème de proxy. Pour cela, il y a un pré-requis : le serveur doit être accessible directement depuis le réseau de développement, et avoir accès à internet (si possible sans proxy). Dans notre cas, c’est Nexus qui fait office de dépôt Maven (mais la même technique doit fonctionner avec Artifactory ou autre…). Ensuite :

  • On configure différents dépôts de type « proxy » vers chacun des dépôts externes dont on a besoin.
  • On ajoute tous ces dépôts au dépôt groupe « public ».

Enfin, nous devons expliquer à Maven qu’il doit systématiquement utiliser notre serveur interne au lieu de tenter d’accéder directement aux dépôts externes (Maven central, etc.). Pour cela, retour dans « settings.xml », mais cette fois dans le bloc mirrors.  Il suffit d’expliquer à Maven que tous les dépôts dont ont a besoin ont pour miroir notre serveur interne :

1
2
3
4
5
6
7
8
<mirrors>
  <mirror>
    <id>nexus.grosclient.com</id>
    <name>Serveur Nexus de Gros client</name>
    <url>http://nexus.grosclient.com/content/groups/public</url>
    <mirrorOf>*</mirrorOf>
  </mirror>
</mirrors>

Avec cette configuration, le paramétrage des proxys fait précédemment doit être supprimé (ou une exception doit être ajoutée pour le dépôt interne).

Cette dernière configuration présente plusieurs avantages :

  • L’ensemble des dépôts susceptibles d’être utilisés dans les différents projets de l’entreprise sont configurés de manière centrale, au niveau du dépôt. Cela permet à l’équipe agile au chef de projet (rappel : nous sommes chez Gros client) de contrôler les dépôts/librairies utilisées sur le projet.
  • Le premier développeur qui demande une librairie au serveur Nexus va déclencher son téléchargement depuis son dépôt initial. Mais celle-ci sera ensuite mise en cache sur le serveur. Ainsi, les appels suivants (par les autres développeurs) se contenteront d’effectuer un téléchargement sur le réseau local, avec un gain de temps (voire de bande passante) non négligeable.
Publié dans Java, Systèmes d'information | Marqué avec , , | Laisser un commentaire

Utiliser Java 7 dans Talend Open Studio

Il y a quelques temps que je n’avais pas retouché à Talend Open Studio. Mais le Talend Partner Summit du mois dernier m’a donné l’occasion de recroiser des connaissances, et d’en apprendre un peu plus sur l’avenir du produit (« plate-forme unifiée », « big-data avec Hadoop« , etc.). Et surtout, ce fut une journée qui m’a donné envie de me replonger un peu dans le produit. En particulier, je me suis posé la question de la possibilité de développer de nouveaux composants en utilisant Java 7. En particulier l’API NIO2 qui apporte de nombreuses fonctionnalités qu’il me semble intéressant d’exploiter :

  • accès (en lecture et en écriture) à de nouvelles propriétés des fichiers : propriétaire, permissions, gestion des liens symboliques et des fichiers cachés, etc.
  • surveillance native des évènements (création/modification/suppression d’un fichier)
  • plus grande simplicité et meilleures performances lors de l’accès et du parcours des fichiers avec Files
  • etc.

Configurer Talend Open Studio

Lancer Talend Open Studio avec Java 7

La première étape est évidemment de se procurer et d’installer le JDK 7. Une fois celui-ci installé, il faut forcer Talend Open Studio à utiliser celui-ci. Cette étape est nécessaire pour permettre l’exécution de traitements utilisant du Java 7 au sein du studio. L marche à suivre ne surprendra pas les habitués d’Eclipse : il faut modifier le fichier ini correspondant à votre programme de lancement à la racine du produit, en lui ajoutant 2 lignes permettant de préciser la JVM de lancement. Dans mon cas (sous Ubuntu), le fichier est TalendOpenStudio-linux-gtk-x86_64.ini :
1
2
-vm
/usr/lib/jvm/java-7-jdk/bin/java
Evidemment, tant le nom du fichier que le chemin du JDK sont à adapter à votre environnement.

Enregistrer le JDK 7 dans le studio

Encore une fois, il s’agit d’une étape classique de l’utilisation d’Eclipse : il faut se rendre dans les « Préférences » du Studio (menu « Fenêtre > Préférences »). De là, le menu qui nous intéresse est « Java > JRE installés ». Il faut alors ajouter le JDK 7, et le définir comme étant celui utilisé par défaut :
Configuration Java dans Talend Open Studio

Configuration Java dans Talend Open Studio

Au passage, on remarque que dans les préférences « Java > Compilateur », le niveau de compatibilité du compilateur ne va que jusqu’à la version 1.6. Cela signifie qu’on ne pourra pas utiliser dans un composant les syntaxes introduites dans Java 7 (Try with resources, « diamond », etc.). En revanche, cela n’interdit pas d’utiliser les nouvelles classes du JDK 7, ce qui nous intéresse !
Enfin, avant de quitter les préférences, faisons un détour par « Java > Style de code > Formateur », afin d’y modifier le style par défaut. En effet, Talend utilise des nom de variables particulièrement longs (car ils contiennent l’identifiant du composant), tels que tos_count_tMSSqlLastInsertId_1. Aussi, lorsque plusieurs de ces variables sont utilisées dans une même instruction, la limite par défaut de 80 caractère à vite fait de la découper en 3 ou 4 lignes, ce qui est particulièrement pénible à relire.
C’est pourquoi je recommande vivement de passer cette limite à 120, 160… voire à 1000 lignes. Le code généré n’en sera que plus facile à relire, pour comprendre ce qui ne va pas.

Utiliser du Java 7 dans Talend Open Studio

L’ensemble des préparatifs étant terminé, il est maintenant possible d’utiliser les classes de Java 7 dans Talend Open Studio :

  • dans les différents composants permettant d’écrire du code directement (tJava, tJavaRow, tJavaFlex, etc.).
  • en créant soit-même de nouveaux composants.
Afin de vérifier le bon fonctionnement de cette manipulation, un premier composant a été créé : le bcFileProperties. Ce composant dérivé du tFileProperties, ajoute la lecture des droits du fichier ainsi que de son propriétaire. Les sources de ce composant sont comme d’habitude disponibles sur GitHub. D’autres composants utilisant les optimisations offertes par Java 7 devraient suivre de la même manière (dès que j’aurai le temps…).
Exécution du composant bcFileProperties

Exécution du composant bcFileProperties

Publié dans Talend | Marqué avec , | Laisser un commentaire

Sauvegarde automatique de l’historique d’un document

Il est des semaines où on doit troquer son IDE préféré pour des outils bizarres tels que OpenOffice LibreOffice, Microsoft Office, voire pire… Microsoft Project. Or avec ces outils, on a vite fait de perdre plusieurs heures de travail avec une fausse manipulation. Afin de palier à ce problème, j’ai mis à contribution un de mes outils préférés : git. Il n’y a pas de raison que les documents ne soient pas versionnés, au même titre que du code. D’autant plus que le coût de mise en place d’une telle sauvegarde est très faible :

1
2
3
git init
git add mondocument
git commit -m 'Première sauvegarde de mon document'

Diff entre deux versions

En commitant régulièrement son document, on en constitue un historique. Et avec les branches, on peut même le décliner en plusieurs versions. Je n’ai par contre pas réussi à créer de « feature branch » documentaire, la fusion automatique de documents binaires avec git se passant bizarrement assez mal.

L’autre problème avec des documents binaires, c’est qu’ils passent assez mal dans le « diff », ce qui fait perdre à la gestion de configuration une partie de son intérêt. Mais pour ce problème là, il existe une solution. Il suffit d’avoir un outil permettant d’afficher un document un mode texte. Dans le cas du format OpenDocument, on peut par exemple utiliser odt2txt.

Il faut ajouter dans .gitconfig le bloc suivant, pour déclarer le convertisseur associé au format odf :

1
2
[diff "odf"]
    textconv=odt2txt

Enfin, dans le répertoire du dépôt du projet, il faut associé ce convertisseur avec les extensions des fichiers OpenOffice. Ca se passe dans le fichier info/attributes :

1
2
3
*.odt diff=odf
*.ott diff=odf
# idem pour les formats ods, ots, odp et otp

Cette modification effectuée, on récupère la possibilité de calculer le différentiel entre deux commits, et toutes les fonctionnalités associées.

Le seul inconvénient, c’est qu’il faut répéter cette opération pour chaque dépôt de documents. Je n’ai pas trouvé le moyen de définir ces comportements dans la configuration globale de git. Si quelqu’un a une solution, je suis preneur !

Automatisation de la sauvegarde

Afin d’améliorer un peu le processus, il suffit d’un petit script shell qui automatise l’enregistrement du document à intervalles réguliers :

1
2
3
4
5
6
7
8
9
#!/bin/sh
# Intervalle entre deux enregistrements
SAVE_PERIOD_IN_SECONDS=120
while :
do
    echo "Autosave : $(date)"
    git commit -a -m "Autosave $(date)"
    sleep $SAVE_PERIOD_IN_SECONDS
done

Ce script utilise une des particularités intéressantes de git : si le fichier n’a pas évolué pendant l’intervalle, le commit n’est pas effectué. Ainsi, l’historique des versions du document pourra sauter des enregistrements (si on a oublié d’enregistrer le document entretemps par exemple).

Pour finir, voici donc le script en action :

Sauvegarde automatique de document avec git

Sauvegarde automatique de document avec git

Publié dans Systèmes d'information | Marqué avec , | Un commentaire

Premiers pas sur CloudBees

Mardi dernier se tenait le traditionnel Paris JUG, recevant Patrick Chanezon venu nous parler du Cloud. Au passage, félicitons l’organisation qui est passée de JugEvent à EventBrite, beaucoup plus fiable (et qui m’a permis d’avoir une des dernières places libérées le jour même de la conférence).

Dans la nuit qui a suivi, Olivier et Nicolas ont respectivement publié des excellents comptes-rendus de cette soirée. Merci et félicitations à eux donc :

Voici donc, modestement, un petit compte-rendu de tests que j’ai eu l’occasion de faire sur deux des plate-formes dont il était question à cette soirée.
Continuer la lecture

Publié dans Systèmes d'information | Marqué avec , , , , | 5 commentaires

Retour sur le BreizhCamp

Vendredi dernier, j’ai eu la chance de pouvoir participer au premier BreizhCamp, organisé entre autres par Nicolas de Loof. Cette journée, agrémentée d’un temps « breton », fût très enrichissante, tant par les conférences elles-mêmes que par les discussions que nous avons pu avoir entre ces sessions.

Une des particularité de cette journée était de ne pas tourner qu’autour de Java, mais aussi d’autres langages (Python, Ruby, .NET). Autre particularité (par rapport à la What’s Next notamment), les thèmes de cette journée étaient moins orienté Cloud, et plus NoSQL.

Voici un petit résumé des conférences qui m’ont le plus intéressé :

Continuer la lecture

Publié dans Divers | Marqué avec , , , , | Un commentaire

99 Scala problems : les 22 premiers

Après quelques articles et tutoriels, ainsi que quelques tests sur les interactions avec Java, j’ai commencé mon apprentissage du Scala par les 99 Scala problems.

Avant de me lancer dans la résolution des problèmes en question, et en application des bonnes pratiques du TDD, j’ai écrit les signatures des méthodes, et les tests associés à ces 22 problèmes. Si vous voulez vous lancer, je vous épargne cette première étape : vous pouvez télécharger directement ce squelette.

Vous pourrez vérifier que les 22 tests échouent. Ces tests sont cependant rudimentaires, et les faire passer au vert ne garantira pas que vous avez la bonne solution (même si c’est encourageant).

D’autres personnes se sont lancées avant moi dans la résolution de ces problèmes. Comme il est toujours intéressant de comparer les différentes approches, en voici quelques unes (en plus des solutions du site original) :

Continuer la lecture

Publié dans Java | Marqué avec , , | Un commentaire

Mettre en place un workflow git

Si vous avez été à une ou deux présentations de git, vous avez sans doute déjà vu ce diagramme (ou un équivalent).

Après avoir un peu pratiqué git, ce genre de workflow devient naturel, et est particulièrement appréciable :

  • les fonctionnalités ont chacune leur branche dédiée : la lecture de son historique n’est donc pas gêné par le reste des développements
  • les livraisons peuvent être préparées sans empêcher les personnes qui travaillent sur les futures fonctionnalités de partager leur travail
  • etc.

Voila pour la théorie : sur le papier, ça laisse absolument rêveur ! Mais dans la pratique, tout ne fonctionne pas aussi bien, surtout au début. Et c’est là que commence mon retour d’expérience sur la mise en place de ce workflow.

Continuer la lecture

Publié dans Systèmes d'information | Marqué avec , , , , | 4 commentaires