Publié par
Il y a 7 années · 12 minutes · Java / JEE

Devoxx – L’avenir de Java

La keynote de Mark Reinhold, Chief Architect de la plate-forme Java chez Oracle, était particulièrement attendue après une actualité très riche sur le JDK ces derniers mois.

L’année dernière, l’annonce d’un nouveau délai pour la sortie de JDK 7, afin de permettre la ré-intégration des closures, avait provoqué la surprise. L’été arrivant, la communauté se rendait alors compte que le planning initial prévoyant un JDK 7 features complete pour juin était déjà dépassé et irréaliste. Quelques mois plus tard, Mark Reinhold annonçait sur son blog un « plan B » : on ne conserverait alors dans JDK 7 que les fonctionnalités déjà implémentées pour repousser celles qui sont encore en cours d’élaboration, telles que les closures ou la modularité, au JDK 8.

Plus récemment l’actualité était marquée par l’annonce de nouveaux entrants dans le projet OpenJDK : IBM dans un premier temps, s’étant résigné à mutualiser ses efforts de développements avec Oracle, et Apple qui après l’annonce de l’arrêt du support de Java dans Mac OS X avait décidé de léguer les développements spécifiques à son OS au projet OpenJDK.

Dans ce contexte rempli de rebondissements et d’incertitudes, Mark Reinhold a apporté quelques clarifications et une visibilité appréciable sur l’avenir de Java.

Productivité

Project Coin

Le projet Coin fait partie de l’actualité Java depuis de nombreux mois maintenant et l’on a pu se familiariser avec la plupart des évolutions du langage qu’il va apporter. Aucun ajout n’a été annoncé aujourd’hui. Rappelons qu’il contient les évolutions suivantes :

  • L’opérateur <> permettant d’instancier facilement des classes génériques en ne répétant pas le(s) paramètre(s). On obtient ainsi (Map<String, String> map = new HashMap<>();).
  • La gestion des ressources via la structure de contrôle try..catch, qui simplifie grandement l’écriture de code d’E/S et résout la confusion autour de la fermeture de flux lançant de multiples exceptions.
  • La prise en charge des string dans les structures switch.
  • Une notation plus lisible pour les constantes numériques.
  • Le multi-catch permettant de capturer en une seule structure plusieurs types d’exceptions.
  • La simplification de l’invocation des méthodes utilisant des varargs.

La réification au secours de l’érasure

Pour des raisons de compatibilité ascendante, les generics ont été ajoutés à Java 5 en procédant par type erasure. Cette technique consiste à ne manipuler les generics que dans le code source et à les faire disparaître du bytecode compilé. Les generics permettent alors uniquement d’effectuer diverses vérifications de typage lors de la compilation mais n’ont aucun apport à runtime. Il est donc impossible d’écrire

Object list = new ArrayList<String>();
if (list instanceof List<String>)
...

De même, la surcharge de méthodes ne se différenciant que par leur type de paramètre generics est impossible.

Très rapidement après l’arrivée de Java 5, ces limitations ont été critiquées. Mark Reinhold affirmait aujourd’hui son souhait de voir la réification de type intégrée dans une future version de Java. La réification consiste en l’ajout du typage generics dans le bytecode rendant ainsi cette précieuse information disponible à runtime.

L’absence de connaissance sur le typage des generics à runtime est également la raison pour laquelle les paramètres ne pouvaient pas être des types natifs. Ignorante du typage des paramètres, la JVM ne pouvait en effet qu’émettre l’hypothèse que ceux-ci héritaient de la classe Object. On peut alors se prendre à rêver à la possibilité d’écrire :

List<int> list = new ArrayList<>;

Et ainsi de se passer de classes de collections spécialement écrites pour ces types natifs. Mais de nombreux défis devront toutefois être relevés pour en arriver là : le passage en paramètre d’un objet est différent de celui d’un type natif, ce qui pourrait mener à des comportements inattendus pour les classes développées avant l’arrivée de la réification et qui supposeraient donc que la modification d’une variable serait propagée au-delà du contexte des méthodes. Ce type de défi lié à l’exigence historique de compatibilité ascendante entre versions de Java est courant pour l’équipe en charge du JDK.

Aucune version de Java n’a été précisée pour la réification, classant donc cette fonctionnalité comme étant « à l’étude » pour le moment.

Les value class

Les value class constituerait une nouvelle famille de types dans Java que l’on peut formaliser comme un javabean intégré au langage. Les différents champs seraient alors exposés sous forme de propriétés. Ce type de classe pourrait prendre la forme suivante :

value class Node {

    Node property parent;
    Node property leftChild;
    Node property rightChild;
}

Le retour des propriétés dans le radar de l’équipe en charge du JDK ravira sans nul doute tous ceux qui sont lassés de devoir s’en remettre à leur IDE pour la génération des getters / setters !

Aucune version n’a malheureusement été spécifiée pour l’intégration de cette fonctionnalité.

Performance

On le sait depuis quelques années, l’amélioration des performances des applications passe dorénavant par l’utilisation du multithreading pour bénéficier de l’augmentation du nombre de cœurs sur les serveurs. Java est armé face à ce défi grâce aux apports liés à java.util.concurrent dans Java 5. L’enjeu est maintenant de rendre ces fonctionnalités plus simples et productives à utiliser.

Les extensions de java.util.concurrent

Java 5 avait introduit un ensemble de classes facilitant l’écriture de programmes parallèles dans le package java.util.concurrent. La JSR-166 (Concurrency Utilities) les avait standardisées. Java 6 avait amené de légères évolutions à ce package qui avait été noté JSR-166x. Java 7 apportera à son tour des avancées dans ce domaine crucial pour l’avenir, sous la forme de la JSR-166y. On compte parmi elles :

  • La très attendue API Fork / Join mais sans le ParallelArray,
  • Une API donnant accès à des possibilités atomiques de bas niveau, permettant à terme la disparition de la classe interne non-standard sun.misc.Unsafe
  • Une TransferQueue et une LinkedTransferQueue pour faciliter la communication entre threads,
  • Une ConcurrentReferenceHashMap permettant la manipulation concurrente de références fortes ou faibles (weak references).

Les closures

Novembre 2009, Devoxx. Une session de Mark Reinhold sur JDK 7 crée l’évènement, il y annonce le retour des closures justifié par le besoin de simplifier le développement multithread. Aujourd’hui les closures sont toujours sur la roadmap, mais décalées au JDK 8.

Le lien qu’Oracle fait entre programmation parallèle et closures s’explique par l’exemple suivant. Ici on souhaite étendre l’API Collection pour offrir des méthodes filter(), map(), ou encore max() qui de manière transparente délègueront au besoin le travail à plusieurs threads :

Collection<Student> students = ...;

double max = students.filter(new Predicate<Student>() {
    public boolean op(Student s) {
        return s.gradYear == 2010;
    }
}).map(new Extractor<Student, Double>() {
    public Double extract(Student s) {
        return s.score;
    }
}).max();

Pour obtenir ce type d’exécution parallèle implicite, il est ici bien entendu nécessaire de fournir une classe anonyme implémentant le code à exécuter. Cette approche est verbeuse et rapidement inadaptée à une application d’entreprise complexe ; suffisamment tout du moins pour éloigner les développeurs de ce type d’API.

Mark Reinhold montre alors ce que pourrait devenir l’exemple précédent avec les closures :

double max = students.filter(#{ Student s -> s.gradYear == 2010 })
                     .map(   #{ Student s -> s.score })
                     .max();

Le code est concis, et une fois la syntaxe basée sur les symboles # et -> assimilée, il s’avère tout à fait lisible.

Les méthodes d’extensions

L’ajout des closures étant destiné à améliorer la programmation parallèle, il doit forcément être accompagné de nouvelles méthodes sur les collections permettant de leur soumettre du code.

Le problème est que l’interface java.util.Collection a été mainte fois implémentée dans diverses librairies et applications. Lui ajouter une méthode casserait donc le code existant.

Les méthodes d’extensions viennent résoudre ce problème en permettant d’adjoindre à la nouvelle méthode une implémentation par défaut. Ainsi dans l’exemple de la classe java.util.Collection on obtiendrait :

Collection<T> filter(Predicate<T> p) default Collections.<T>filter;

L’implémentation par défaut est alors une méthode statique définie dans une classe tierce et qui prend en premier argument l’objet sur lequel s’applique la méthode. Dans l’exemple précédent, le prototype de la méthode d’extension filter() serait donc :

static <T> Collection<T> filter(Collection<T> collection, Predicate<T> p);

Modularité

Jigsaw reste l’avenir de la modularité

Le besoin pour un mécanisme de modularité intégré au langage se fait ressentir pour assurer la logique d’encapsulation au-delà des frontières des classes. Parallèlement, Maven a montré l’intérêt d’une gestion de versions pour ces modules.

A l’heure actuelle, il semble qu’OSGi peinera a être accepté comme solution de modularisation pour Java. Sa complexité a probablement contribué à rendre SpringSource dm Server trop peu attractif pour attirer un large public. Dès lors, la voie est libre pour Jigsaw pour proposer une solution simple et efficace à cette problématique.

Mark Reinhold ne s’est pas étendu en détails sur Jigsaw mais a exprimé fermement son souhait de le voir remplacer à terme la notion de classpath aujourd’hui inadaptée aux applications complexes et denses que l’on connaît.

Gestion des dépendances

Maven est de nos jours omniprésent dans les entreprises. Cet outil s’est imposé au fil des années comme un standard dans la gestion des dépendances Java : même ses concurrents tels qu’Ivy ou Gradle sont basés sur le système de définition des modules de Maven et sur son réseau de dépôts.

Java se dotant d’un mécanisme de modules, une intégration intelligente se devait d’exister. Mark Reinhold a ainsi expliqué que Maven serait pris en compte pour la gestion et le téléchargement des modules Java sur la machine.

Là encore, aucune version n’est spécifiée pour l’intégration de Maven avec Jigsaw, mais on peut logiquement imaginer (ou tout du moins espérer) son arrivée pour le JDK 8.

D’autres formats que le Jar

Mark Reinhold a surpris l’audience avec cette annonce. Il s’agirait de permettre d’autres formats de packaging pour les applications Java que le jar. On parle tout d’abord d’un nouveau format baptisé jmod qui serait basé sur une autre compression que zip, telle que pack200.

Mais la réflexion va plus loin en envisageant d’étendre les formats de packaging jusqu’aux archives propres aux systèmes d’exploitation de production tels que rpm ou deb. Ceci simplifierait grandement les déploiements et les interactions avec les équipes d’exploitation !

La roadmap

Après avoir énoncé les différentes évolutions, il fallait forcément aborder l’épineuse question du planning. Les retards successifs de JDK 7 laissent planer le doute quant à la date de finalisation effective, mais reconnaissons que l’allègement de la liste des fonctionnalités de JDK 7 rend cette fois la roadmap plus réaliste ; la plupart des fonctionnalités restantes étant en effet déjà implémentées. Le calendrier présenté par Mark Reinhold et posté sur le site du projet OpenJDK quelques heures plus tard est le suivant :

  • 16/12/2010 : Feature Complete
  • 12/04/2011 : Rampdown start: P1-P3 bugs only
  • 28/04/2011 : API/interface changes: Showstoppers only
  • 11/05/2011 : All targeted bugs addressed, First release candidate built
  • 18/05/2011 : Bug fixes: Showstoppers only
  • 08/06/2011 : Final test cycle starts
  • 28/07/2011 : General Availability

Les aspects politiques

Oracle et Java

Mark Reinhold a également consacré quelques instants pour évoquer les aspects politiques qui entourent Java. Les inquiétudes sont en effet nombreuses au sein de la communauté : on reproche souvent à Oracle son comportement très agressif vis-à-vis des autres acteurs du marché ainsi que de sa vision parfois éloignée du monde de l’Open Source.

Son message se voulait clair sur cette question : l’intérêt d’Oracle est d’assurer la pérennité de Java, dans la mesure où nombre de ses produits commerciaux sont basés sur cette plate-forme.

Les nouveaux entrants dans l’OpenJDK

L’OpenJDK a vu ses troupes s’enrichir de deux soutiens majeurs ces dernières semaines : IBM et Apple.

IBM avait rejoint le projet un mois auparavant dans un but de mutualiser les efforts de développement avec Oracle et reconnaissant par ce geste implicitement un intérêt commun à assurer l’évolution, la stabilité et la pérennité de la plate-forme Java, supportant nombre de leurs produits commerciaux.

L’annonce du ralliement d’Apple est encore plus récente. Apple avait en effet exprimé son souhait de ne plus assurer le support de Java dans son OS à l’avenir, puis avait annoncé léguer les développements spécifiques à Mac OS X au projet OpenJDK.

Mark Reinhold s’est logiquement montré enchanté de ces divers ralliements permettant de concentrer les différentes forces au développement futur de Java.

Conclusion

Mark Reinhold s’est attaché à formaliser les objectifs qu’Oracle se fixe pour l’avenir du langage Java : conserver la facilité de lecture du langage, plus importante à leurs yeux que la productivité d’écriture. Pour cela chaque nouvelle fonctionnalité est évaluée avec soin afin de déceler les potentiels effets secondaires qu’elle pourrait provoquer. Mark Reinhold expliquait ainsi son souhait de voir Java encore présent en 2030.

Le planning à venir ne s’étalant que sur les 6 prochains mois, il sera aisé de se rendre compte de la potentielle ponctualité de Java 7. Le niveau d’avancement actuel permet toutefois d’être très confiant quant à sa finalisation courant 2011. Les fonctionnalités plus audacieuses de Java 8 pourraient par contre repousser ce dernier au-delà de 2012…

Michaël Figuière
Michaël est consultant chez Xebia où il intervient notamment sur des sites Web à fort trafic. A son aise tant avec les environnements JEE qu'avec les technologies de plus bas niveau, il est spécialisé dans les architectures distribuées et les technologies innovantes telles que NoSQL, les moteurs de recherche, ou encore le data mining.

4 thoughts on “Devoxx – L’avenir de Java”

  1. Publié par Loic, Il y a 7 années

    Merci pour ce résumé, l’exemple des closures est très parlant

  2. Publié par abderrahmen, Il y a 7 années

    Merci pour ce grand sujet, je pense que la langue Java est très forte, Surtout en termes de Web.

  3. Publié par java, Il y a 7 années

    Est-ce qu’une version est déjà spécifiée pour l’intégration de Maven avec Jigsaw ?

  4. Publié par java, Il y a 7 années

    Bonnes présentations. C’est vraiment intéressant comme sujet!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *