Somewhere between Dev and Ops

cat /dev/ops | grep gc

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).

Comments