Somewhere between Dev and Ops

cat /dev/ops | grep gc

Introducing jenv, a command line Java/JDKs Manager

| Commentaires

Introduction

As a developer, it is sometimes necessary to have multiple JDKs installed on the same development machine in order to test the latest JDK 8, or to use a proprietary JDK like the IBM one. But even if there are several installed, when you type java, the first one “java” on the PATH will be used.

With Linux, a tool exists : Alternative. This one creates a symbolic link that points to the JAVA_HOME you specified. When you want to change of JDK, Alternative will change this link. If Alternative is very usefull for managing JDK on a server, it does not answer the need for a development station.

To fit these needs, one way is to manage manually the JAVA_HOME and PATH environment variables. To simplify the switching, there is some scripts that may help, like this one Alternative.

However, these scripts help the switch but does not automate it. You always have to type “setjdk” when you change of project.

When you look at the ruby worl, there is a very handy tool : rbenv. This allows facilities to manage different versions of ruby and choose per project which is the version that you want to use. And once you setup it, you only have to type ruby, and rbenv will use the selected version automatically and transparently.

After some research, I have found no equivalent tool for Java and I took the initiative to create it : jenv

Get started

Installation

For now, the installation is manual. You simple clone the Github project into $HOME/.jenv directory.

1
git clone https://github.com/hikage/jenv.git ~/.jenv

Next, you have to activate it by inserting this commands into the shell init script ( .bash_profile, .zshrc)

1
2
export PATH="$HOME/.jenv/bin:$PATH"
eval "$(jenv init -)

Setup

One installed, you have to setup one or more JDK by using jenv add command. This one take one parameter : the path to a valid JAVA_HOME directory

1
2
$ jenv add /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ jenv add oracle-1.7.0 /Library/Java/JavaVirtualMachines/jdk17011.jdk/Contents/Home

Through jenv versions command, you can list the recognized JDKs.

1
2
3
4
$ jenv versions
* system (set by /Users/hikage/.jenv/version)
  oracle-1.6.0.39
  oracle64-1.7.0.11

The asterisk * denotes the JDK currently used. With no specific configuration it’s the “system” JDK to be used, that means the first found on the PATH. It is possible to change the default version with jenv global <alias name>.

1
$ jenv global oracle64-1.7.0.11

You can hit “TAB” after jenv global to have autocompletion for the alias name. The jenv versions now show that the oracle64-1.7.0.11 will be used.

To configure a JDK per directory/project, you can use jenv local <alias name>

1
2
3
4
5
6
7
$ pwd
/Users/hikage/demo
$ jenv local oracle-1.6.0.39
$ jenv versions
  system
* oracle-1.6.0.39 (set by /Users/hikage/demo/.java-version)
  oracle64-1.7.0.11

To work, jenv store the java version to be used into the .java-version file in the directory. If no .java-version file found, jenv will look into the parent directory, and so on. If none is found, then jenv will switch to the default JDK ( setup by jenv global )

Jenv also has plugins to use the correct version of java with other tools: * Maven * Ant * Gradle * Groovy * Scala * SBT * Play

In addition to JDK management, jenv can also configure JVM paremeters per project :

1
2
$ jenv local-options "-Xms128m -Xmx1024"
$ jenv global-options "-Xms128m -Xmx1024"

And they are also exported via the right environment variables to be used by Maven (MAVEN_OPTS) Gradle (GRADLE_OPTS) or Ant (ANT_OPTS).

Jenv is young, and will be improved

Jenv is very recent, and provides only simple functionalities that I needed for the moment. It is not yet complete, and has to be improved.

The project is on GitHub, so feel free to fork and contribute ideas (by pull requests or issues).

Gérer vos JDKs avec jenv

| Commentaires

Introduction

En tant que développeur, il est parfois nécessaire d’avoir plusieurs JDKs installés sur notre machine de développement. Que cela soit pour tester les derniers nouveautés du JDK 8, ou bien avoir un JDK propriétaire tel que celui de IBM.

Sous Linux, il existe Alternative qui apporte une solution pour gérer ces différentes installations. Pour l’utiliser, il faut tout d’abord le configurer pour lui faire connaitre les différents JDKs disponibles :

1
2
$ alternatives --install /usr/bin/java java /usr/java/jdk1.6.0_11/bin/java
$ alternatives --install /usr/bin/java java /usr/java/jdk1.7.0/bin/java


Ensuite, il est possible de lister et choisir lequel utiliser :

1
$ alternatives --config java


Cette commande modifie le lien symbolique /usr/bin/java pour pointer vers celui sélectionné.

Cette solution est élégante, mais possède quelques limitations pour une poste de développement :

  • alternatives nécessite des droits root (directement, ou via sudo). Après, si c’est votre poste personnel, j’imagine que c’est le cas.
  • alternatives modifie un lien global, une modification impacte tout les utilisateurs, tout les shells.
  • alternatives ne permet pas de configurer quel version de Java d’autres outils tels que Maven, Ant ou Gradle utiliseront.

A l’occasion de la migration de ce blog vers Octopress, j’ai eu l’occasion de découvrir l’écosystème Ruby, et en particulier rbenv. Cet utilitaire permet de gérer et spécifier quelle version de Ruby doit être utilisée, et cela globalement par utilisateur, ou plus spécifiquement sur un répertoire.

J’ai cherché une solution identique pour Java, mais sans réussite. Par chance, rbenv étant OpenSource, j’ai pu me baser sur celui-ci pour créer un équivalent pour Java que j’ai nommé : jenv.

Quick Start avec jenv

Installation

Pour l’instant, l’installation est manuelle, en clonant le dépôt git au bon endroit :

1
git clone https://github.com/hikage/jenv.git ~/.jenv

Ensuite, il faut ajouter jenv dans le $PATH et activer celui-ci. Le mieux étant de faire cela dans le bon fichier ( .bash_profile, .zshrc) :

1
2
export PATH="$HOME/.jenv/bin:$PATH"
eval "$(jenv init -)

Pour les utilisateurs de Mac, il est également possible d’utiliser homebrew :

1
brew install https://raw.github.com/hikage/homebrew/master/Library/Formula/jenv.rb

Utilisation

Une fois installé, il est également nécessaire d’ajouter les différents JDKs dans jenv, via la commande jenv add qui prend deux paramètres : * Un nom unique qui sera utilisé comme alias * Le chemin vers le JAVA_HOME du JDK

1
2
$ jenv add oracle-1.6.0 /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ jenv add oracle-1.7.0 /Library/Java/JavaVirtualMachines/jdk17011.jdk/Contents/Home

Via la commande jenv versions, il est possible de lister les JDKs configurés :

1
2
3
4
$ jenv versions
* system (set by /Users/hikage/.jenv/version)
  oracle-1.6.0
  oracle-1.7.0

L’astérisque* désigne le JDKs utilisé actuellement. Sans configuration spécifique, il utilisera tout le temps le Java “system”, c’est-à-dire celui qu’il trouvera dans le PATH. Il est possible de changer cette version par défaut :

1
2
3
4
5
$ jenv global oracle-1.7.0
$ jenv versions
  system
  oracle-1.6.0
* oracle-1.7.0 (set by /Users/hikage/.jenv/version)

La commande jenv global a pour but d’écrire la version de Java à utiliser dans le fichier $HOME/.jenv/version.

Configurer un JDK pour un projet en particulier se fait via la commande jenv local, qui fonctionne exactement de la même manière :

1
2
3
4
5
6
7
$ pwd
/Users/hikage/demo
$ jenv local oracle-1.6.0
$ jenv versions
  system
* oracle-1.6.0 (set by /Users/hikage/demo/.java-version)
  oracle-1.7.0

Afin de déduire la version de Java à utiliser, jenv va tout d’abord chercher un fichier .java-version dans le répertoire courant, puis dans le répertoire parent, et ainsi de suite. S’il n’en trouve pas du tout, il utilisera la valeur globale, définie dans $HOME/.jenv/version

Petit plus intéressant, une fois la version de Java définie, jenv va exporter celle-ci via la variable $JAVA_HOME. Et via une possibilité de plugin, jenv intercepte les appels à Maven, Gradle ou Ant afin que ceux-ci utilisent également la bonne version de Java.

1
2
3
4
5
6
7
$ mvn -version
Apache Maven 3.0.4 (r1232337; 2012-01-17 09:44:56+0100)
Maven home: /usr/share/maven
Java version: 1.7.0_11, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk17011.jdk/Contents/Home/jre
Default locale: fr_FR, platform encoding: UTF-8
OS name: "mac os x", version: "10.6.8", arch: "x86_64", family: "mac"

Au delà de gérer la version de Java, jenv permet également de configurer des arguments de la JVM :

1
2
$ jenv local-options "-Xms128m -Xmx1024"
$ jenv global-options "-Xms128m -Xmx1024"

Et ceux-ci sont également exportés via les bonnes variables d’environnement afin d’être pris en compte par Maven (MAVEN_OPTS), Gradle (GRADLE_OPTS) ou Ant (ANT_OPTS).

Jenv ne fait que commencer

jenv est tout récent, et n’apporte que de fonctionnalités que j’ai eu besoin pour l’instant. Il n’est pas parfait, et ne demande qu’a être amélioré.

Le projet est sur GitHub, n’hésitez donc pas à le forker et apporter des idées (par pull request ou par issue).

Les agents Java

| Commentaires

Les Agents Java

Les Agents Java ? Pas la moindre idée de ce que c’est ? Mais si, vous en avez certainement déja vu, ils se cachent dans la ligne de commande Java via ce paramètre -javaagent:vers/mon/agent.jar.

Ceux-ci interviennent lors du chargement des classes par un classloader, et ont la possiblité de venir modifier la classe en cours de chargement. Ce mécanisme est utilisé par divers outils et frameworks :

  • AspectJ pour faire du tissage d’Aspect au chargement
  • Par des outils de Profiling pour venir ajouter du code permettant de tracer les appels
  • … et plein d’autres

Getting started !

Pour mieux comprendre comment fonctionne un agent, le plus simple est de tenter d’en faire un simple.

Créer la classe de l’agent

1
2
3
4
5
6
7
8
9
10
package be.hikage.agent;

import java.lang.instrument.Instrumentation;

public class AgentSimple {

  public static void premain(String agentArgument, Instrumentation instrumentation){     
      System.out.println("Hello, Agent Smith ! [ " + agentArgument + "]");
  }
}

La méthode premain(String agentArgument, Instrumentation instrumentation) est pour un agent ce qu’est la méthode main(String ... arguments) est pour une application Java.

Cette méthode appelée lors du chargement de l’agent, et possède deux arguments :

  • String agentArguments : Ce sont les options passée en paramètre dans la ligne de commande pour l’agent. -javaagent:jarpath=parametre
  • Instrumentation instrumentation, est un service qui va fournir des méthodes pour modifier les classes.

Préparer le packaging

Mais avoir la classe ne suffit pas pour avoir un agent utilisable. En effet, un agent doit obligatoirement un jar, avec un manifest correctement configuré.

Celui-ci doit contenir une entrée Premain-Class

1
2
Manifest-Version: 1.0
Premain-Class: be.hikage.agent.AgentSimple

Tester l’Agent

Une fois le Jar prêt, il faut le tester. Pour cela créer un petit programme simple :

1
2
3
4
5
6
public class TestMain {

  public static void main(String[] args) {
      System.out.println("Mon Programme");
  }
}

Et lançons celui-ci en fournissant l’agent :

1
2
3
$ java -javaagent:AgentSimple.jar="Mes paramètres" be.hikage.agent.TestMain
Hello, Agent Smith ! [ Mes paramètres]
Mon Programme

On remarque que l’agent est bien lancé avant l’application, et qu’il a bien reçu les paramètres que l’on lui a fourni.

Interception des chargements de classes

Voyons maintenant à quoi sert le deuxième paramètre fourni à la méthode Premain : Instrumentation. La principale fonctionnalité de celui-ci est de permettre d’enregistrer un ClassFileTransformer. Cette interface oblige à implémenter une unique méthode :

1
2
3
4
5
6
7
byte[]
    transform(  ClassLoader         loader,
                String              className,
                Class            classBeingRedefined,
                ProtectionDomain    protectionDomain,
                byte[]              classfileBuffer)
        throws IllegalClassFormatException;

Le premier paramètre étant le classloader impliqué pour le chargement de la classe. Les deux suivant, le nom de la classe et l’instance de Class représentant la classe en train d’être chargée. Le dernier est le bytecode brut de la classe, sous la forme d’un tableau de bytes.

Modifions maintenant notre agent pour afficher les classes en cours de chargement :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package be.hikage.agent;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

public class AgentSimple {

  public static void premain(String agentArgument, Instrumentation instrumentation){     
      System.out.println("Hello, Agent Smith ! [ " + agentArgument + "]");

        instrumentation.addTransformer( new ClassFileTransformer() {
            @Override
            public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
                System.out.println("Tu es en train de charger la classe :" + className);
                return classfileBuffer;
            }
        });
  }
}

Le résultat sera le suivant :

1
2
3
4
5
6
7
8
Hello, Agent Smith ! [ Mes paramètres]
Tu es en train de charger la classe : sun/launcher/LauncherHelper
Tu es en train de charger la classe : java/lang/Enum
Tu es en train de charger la classe : be/hikage/agent/TestMain
Tu es en train de charger la classe : java/lang/Void
Mon Programme
Tu es en train de charger la classe : java/lang/Shutdown
Tu es en train de charger la classe : java/lang/Shutdown$Lock

Modification de classe

Passons maintenant la seconde, et tentons de venir modifier les classes en cours de chargement afin d’avoir des statistiques sur le nombre d’instance. Pour cela, il suffit d’ajouter un champ statique qui servira de compteur, et de modifier les constructeurs pour y ajouter une incrémentation de celui-ci ainsi que de l’afficher dans les logs.

Pour cela, il faut utiliser un outil de manipulation de bytecode tels que Javassist. Voici une implémentation d’un ClassFileTransformer possible :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package be.hikage.agent;

import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtField;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

public class CountInstanceTransformer implements ClassFileTransformer {


    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        return visitClass(className, classBeingRedefined, classfileBuffer);

    }

    private byte[] visitClass(String className, Class<?> classBeingRedefined, byte[] classfileBuffer) {
        ClassPool pool = ClassPool.getDefault();
        CtClass cl = null;
        try {
            cl = pool.makeClass(new java.io.ByteArrayInputStream(classfileBuffer));
            if (cl.isInterface() == false) {

                // Ajout d'un champ static dans la classe
                CtField field = CtField.make("private static long _instanceCount;", cl);

                cl.addField(field);

                CtBehavior[] constructors = cl.getDeclaredConstructors();
                for (int i = 0; i < constructors.length; i++) {
                    // On incrémente le compteur et on l'affiche
                    constructors[i].insertAfter("_instanceCount++;");
                    constructors[i].insertAfter("System.out.println(\"" + className + " : \" + _instanceCount);");


                }

                // Génération du bytecode modifié
                classfileBuffer = cl.toBytecode();
            }
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (cl != null) {
                cl.detach();
            }
        }
        return classfileBuffer;
    }
}

Et un petit programme de tests :

1
2
3
4
5
6
7
8
9
10
11
public class TestMain {

  public static void main(String[] args) {
      System.out.println("Mon Programme");
        List test = new ArrayList();
        test.add(new MonObject()) ;
        test.add(new MonObject()) ;
        test.add(new MonObject()) ;
        test.add(new MonObject()) ;
  }
}

Le lancement de l’agent se fait de la même manière qu’auparavant. Cependant, celui-ci apporte une dépendance supplémentaire, Javassist, au runtime. Il faut donc que celui-ci soit disponible dans le classpath :

1
2
3
4
5
6
7
8
9
10
11
12
13
$ java -classpath "path/to/javassist-3.14.0-GA.jar:./" -javaagent:AgentSimple.jar="Mes paramètres" be.hikage.agent.TestMain
Hello, Agent Smith ! [ Mes paramètres]
java/lang/Enum : 1
sun/launcher/LauncherHelper : 1
Mon Programme
be/hikage/agent/MonObject : 1
be/hikage/agent/MonObject : 2
be/hikage/agent/MonObject : 3
be/hikage/agent/MonObject : 4
java/lang/Shutdown$Lock : 1
java/lang/Shutdown$Lock : 2
java/lang/Shutdown$Lock : 3
java/lang/Shutdown$Lock : 4

Conclusion

Les Agents Java sont assez simple à mettre en place, et les possibilités sont assez nombreuses. Cependant, cela nécessite d’avoir déclarer celui-ci au démarrage de l’application.

Et parfois, on aimerait avoir la possibilité d’activer un agent plus tard, au besoin. Pour cela, il existe une API, l’Attach API. Celle-ci fera l’objet d’un prochain article.

Installer CRaSH sous Mac OS X

| Commentaires

CRaSH, c’est quoi ?

Derrière un nom qui ferait fuir n’importe qui, se cache un outil assez prometteur. CRaSH est un projet Open Source, sous licence LGPL, créé par Julien Viet. Et plus exactement un Shell qui permet de se connecter à une JVM et de la contrôler à l’aide de commande développée en Groovy.

Il est assez extensible, mais de base il vient avec des commandes pour JDBC, le logging, les Thread. Pour en savoir plus, je vous recommande la lecture de la documentation, de regarder un screencast ou de parcourir les slides de Julien lors de son quickies à Devoxx France

Comment l’installer ?

CrAsh est disponible sous la forme d’une archive tar.gz. Mais sous Mac OS X, il est maintenant possible de l’installer facilement via Homebrew.

Si vous n’avez pas encore installer ce package manager pour Mac OS X, il vous faudra tout d’abord installer

Une fois fait, l’installation de Homebrew se fait via cette commande :

1
2
/tmp/temp_textmate.AZ9yKo:2: warning: variable $KCODE is no longer effective; ignored
/usr/bin/ruby -e "$(/usr/bin/curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)"

Une fois homebrew installé, l’installation de CRaSH est très simple :

1
2
brew update
brew install crash

And that’s all :-)

Devoxx France

| Commentaires

Le début du rêve

L’histoire a commencé à Anvers, durant une keynote à Devoxx de Stefan Janssens où il lance une bombe atomique. En collaboration avec l’équipe du ParisJUG, ils ont commencé à préparer en secret LA conférence de France : Devoxx France.

Cette conférence reprend les mêmes concepts de l’original, mais en plus court : 1 jour d’université, 2 jours de conférences. Mais France oblige, une majorité de présentation seront en français.

A ce moment, ayant déja fait plusieurs conférences dans les JUGs, j’espérais faire un jour une présentation à Devoxx. Malheureusement mon anglais n’étant pas assez au point, ce n’était pas pour demain. Mais Devoxx France était pour moi la solution idéale, et je me voyais bien un jour y venir présenter un sujet.

De retour d’Anvers, l’idée me trotte dans la tête, mais ma présentation sur les nouveautés de Spring 3.0 n’est plus d’actualité… Et je ne maitrise pas d’autre sujet  suffisement pour être prêt dans les temps.

Bref, je me dis que Devoxx France, c’est pas encore pour tout de suite !

Coup de pouce !

Mais quelques semaines plus tard, SpringSource annonce la sortie de Spring 3.1 ! Je lance l’idée sur Twitter de refaire le tour des JUGs, et Julien Viet (MarsJUG) fut le premier à rapidement m’inviter.

Invitation du MarsJUG

Et dans la foulée/folie, je réponds au Call for Paper de Devoxx France !

Mais si au fond de moi j’espèrais sincèrement être repris, j’étais en même temps assez pessimiste. Depuis l’arrivée de JEE6, Spring est devenu le vilain petit canard, et n’attire plus les foules, et donc que les chances d’être repris pour Devoxx France étaient assez minces.

Peu de temps après, Pierre Antoine Grégoire envoie un email à Henri Gomez  et moi même afin de nous proposer un trio sur un thème qui nous intéresse  : DevOps. L’idée nous plait, et rapidement nous invitons deux autres mercenaires dans le projet : Arnaud Héritier et Dimitri Baeli.

Le sujet est passionnant, les mercenaires motivés .. mais l’organisation sera difficile : nous sommes  géographiquement éparpillés.

Mais on se lance, et on fini par soumettre notre proposition sur le tard !

Fermeture du CFP…

… le stress monte ! Il y a eu énormement de soumissions :

Dès la fermeture du call, chaque minute d’attente est un vrai supplice ! :-)

C’est le jeudi 16 Février quand, a peine levé, je regarde mes emails sur mon smartphone que je vois un émail d’Henri qui dit :

Je suis partagé entre une immense joie, de l’excitation et un stress immense !!!! Il nous va falloir bosser dur pour mettre en place notre présentation, de longues soirées s’annoncent !

Et la semaine qui suit, je reçois un message privé de Nicolas Martignole qui m’informe que mon talk Spring est accepté également. Je suis super heureux, mais la pression monte d’un cran :-)

Préparations et répétition

Et c’est la que je me suis rendu compte que l’off-shore ne pourra jamais fonctionner ! Nous étions à 5, super motivés, sur le même fuseau horaire, et malgré cela, il était déjà super difficile d’être disponible ensemble régulièrement.

Afin de s’organiser, nous avons utiliser Trello qui est super pratique pour la collaboration

Finalement avec l’aide de Trello, Skype, Google Doc, Bitbucket et Email, le projet à finir par aboutir… Mais jusqu’ici aucune répétition à 5 n’avait pu être effectuée. Et donc pour combler ce manque, une “répétition générale” a été programmée au YaJUG .. 2 jours avant notre passage à Devoxx France.

Le weekend juste avant, Arnaud Héritier nous informe que le staff n’est pas super confiant vis-à-vis de la connexion internet, et ce même pour les speakers… Or, notre démo se base sur Amazon EC2 … Autrement dit, pas de réseau, pas de démo.

Gros STRESS !!! Pierre Antoine et Henri ont passé une bonne partie de leur weekend à tout rendre possible dans une simple VM VirtualBox locale.

C’est dans ce contexte hasardeux que nous avons tenté la répétition au YaJUG, à 4 mercenaires et demi ( Henri n’ayant pas pu nous rejoindre physiquement mais en conf-call). Ce fut également pour moi l’occasion de rencontrer Arnaud et Dimitri et ainsi mettre une tête sur un nom.

La répétition fut, disons … intéressante :-) Mais elle n’a pas réduit mon stress, bien au contraire.

Direction Paris

Le mardi soir, départ pour Paris à partir de Luxembourg, en voiture. Le GPS annonce l’arrivée prévue à 21h30. C’est tard, mais cela laisse un peu de temps pour se retrouver (finalement) à 5 pour discuter et revoir la présentation.

C’était sans prévoir les soucis sur la route. Je suis arrivé à l’hotel vers 22h30. Pierre Antoine me téléphone pour m’informer que l’on se retrouverait finalement le lendemain vers 7h30-8h… Avec un passage à 9h30…

Résultat, j’ai pas réussi à dormir :-)

Le Jour J

Et comme la loi de Murphy gagne toujours, on fut enfin réuni  à … 8h45 ! C’est donc avec un briefing d’environ 30 minutes qu’on est finalement apparu devant notre public.

Et globalement, la présentation s’est super bien passé, les retours ont été très positifs… même si on a tout de même réussi à dépasser un peu du temps imparti.

Le Jour J - Juste après

Et bien je ne sais pas si c’est du fait de la digestion des sandwiches ou bien parce que le gros stress retombait, ou encore que j’ai pas vraiment dormi de la nuit, mais j’ai été complètement naze pendant 3h … et pas en état pour participer à une université, même si plusieurs sujets m’intéressaient fortement.

Donc globalement, j’ai pas vraiment profiter de la première journée de Devoxx France. Ni même de la soirée “speaker” en fait, car le stress de ma deuxième participation s’est fait sentir, et je suis rentré tôt à l’hotel.

Le Jour J2

Le deuxième jour, il y avait de super keynotes ! Enfin il parait, moi j’étais dans la salle speaker à revoir ma présentation :-)

En effet, si j’en étais pas à ma première conférence sur Spring, la grosse nouveauté fut de respecter un timing de 55 minutes, questions comprises. J’avais donc réduit fortement le contenu de ma présentation, peut être trop finalement.

Et bien, je m’en suis pas trop mal sorti, même si je râle sur moi même de m’être trop attardé sur la première partie de ma présentation, par peur de ne pas avoir assez de contenu… Je n’aurais pas du ! J’ai du accélérer sur la deuxième partie qui était certainement la plus intéressante. Ce fut une bonne expérience, et je travaillerais le timing nettement plus pour une prochaine participation.

J’espère qu’elle aura tout de même été appréciée.

Le Jour J2 - Ou le début de Devoxx :-)

Mes deux présentations passées, j’ai enfin pu profiter de Devoxx pleinement, l’esprit enfin ouvert à cette ambiance si proche de ce que j’ai connu à Devoxx Anvers.

Et pour les francophones, Devoxx France n’avait pas grand chose à envier à Devoxx “World”. L’organisation était impeccable, les sujets présentés nombreux et super intéressants. Ce fut également l’occasion de revoir des connaissances que je ne croise que trop rarement ndeloof, @juliendubois, @framiere, et j’en passe) ou de mettre des visages sur d’autres  (Imifos, @jponge ou encore @olamy.

En tant que Sfeirien Luxembourgeois, Devoxx France m’a permis de rencontrer une partie de l’équipe Parisienne, en particulier le staff administratif qui n’est pas présent à Anvers ;-) J’en ai profité pour entamer une discussion avec Didier sur ce qu’il serait possible de faire pour créer des liens entre les équipes des deux pays.

Bref, j’ai participé à Devoxx France

Même si effectivement, je n’ai pas réussi à profiter des conférences à 100%, ce fut tout de même une excellente aventure.

Si toi aussi, tu es passionné, et que tu as envie de partager un sujet avec d’autre, je te conseille de tenter ta chance l’année prochaine. Et ne te bloques pas sur le fait que tu n’es pas (encore) une Rock Star …

Regarde moi, je ne le suis pas non plus ! Je n’ai pas écrit de livre, je n’ai pas inventé de framework révolutionnaire. Et non, je ne suis pas non plus employé de SpringSource ! ;-)

Je ne suis qu’un simple gars qui a découvert Spring Framework il y a quelques années. J’ai trouvé ce framework super génial, j’ai voulu mieux le faire connaitre. Et malgré l’arrivée de JEE 6, je pense qu’il a toujours sa place, et j’avais envie de le dire à tout le monde :-)

Donc arrêtes  d’ennuyer tes collègues avec un outil ou framework qui te passionne, et tentes ta chance l’an prochain à Devoxx France, tu ne le regretteras pas !