Ce n'est pas qu'un slogan politique mais bien la réalité pour Java depuis l'année écoulée.
A tel point que plusieurs caractéristiques historiques de Java sont partiellement remises en cause notamment la lenteur patente entre deux releases, l'embonpoint endémique du JRE/JDK, et même la sacro sainte rétro-compatibilité, ... Faisons un tour de ces évolutions qui sont parfois de profonds changements.
Lyon JUG 2018 - Java le changement c'est maintenant
1. 1
Java, le changement
c'est maintenant
(... enfin depuis un an déjà)
Java, le changement
c'est maintenant
(... enfin depuis un an déjà)
Jean-Michel Doudoux
@jmdoudoux
Jean-Michel Doudoux
@jmdoudoux
Lyon,
19 décembre 2018
2. 2
Made Java great again ?
Java 8
TIOBE : langage de l’année en 2005 et en 2015
Un engouement certain
constaté par la popularité de Java 8
Diffusé en mars 2014
Fin des patches gratuits annoncée pour janvier 2019
Pour les entreprises utilisant Java sans support
3. 3
Sûrement la version la plus controversée
Java 9
Première fois que l’EC du JCP vote Non
Diffusé en septembre 2017
2 updates : 9.0.1, 9.0.4
Introduit des changements majeurs
Tout en tentant d’offrir une certaine compatibilité
4. 4
Depuis un an
De nombreux changements dans l’écosystème Java
Nouveau modèle de releases
Des annonces majeures
Des mises en Open Source
Trois releases : Java 9, 10 et 11
6. 6
• Des changements stratégiques majeurs depuis un an
• Java 9
• Java 10
• Java 11
• Les fonctionnalités dépréciées ou retirées
• Faire un état des lieux avant migration
• Les stratégies de migration de Java 8 vers 11
• Les principales difficultés
Roadmap
8. 8
Qui induisent de nombreuses interrogations
De nombreux changements
De la confusion
Augmentées par
un certain manque d’informations
des informations parfois contradictoires
Des doutes voire de fortes craintes
9. 9
Java 9 : les fonctionnalités
API
Fabriques pour des collections immuables
Process API
Reactive Streams (Flow API)
Var Handles
…
Le système de modules (JPMS) issu du projet Jigsaw
Introduit une rupture
Avec un mode de compatibilité, pour faciliter la migration
Evolutions mineures dans le langage
Outils
JShell
Jlink pour créer des runtime compacts
Recherche dans la Javadoc en HTML 5
Jdeprscan
…
JVM
G1 est le ramasse-miettes par défaut
Réduction de la taille mémoire (Compact Strings)
Amélioration de la performance et de la sécurité
Multi-Release Jar
…
+ 89 JEPs
10. 10
Le classpath est remplacé par le module-path
Mythes et réalités
Le code de l’application doit être modularisé
sun.misc.Unsafe est retiré
NON
NON
NON
Une application Java 8 s’exécute en Java 9+
La majorité du code existant n'aura pas besoin d'être modifié
Une application Java 8 compile en Java 9+ Ça depend
Ça depend
OUI
11. 11
Nouveau modèle de releases
2 releases majeures de Java par an (OpenJDK) :
Feature releases en mars et septembre
Update releases en janvier, avril, juillet et octobre
Les deux releases suivantes après Java 9 :
Java 10 le 20 mars 2018
Java 11 le 25 septembre 2018
Mises à jour OpenJDK uniquement pour la version courante
Avantages
Fonctionnalités proposées plus rapidement
Dès qu’elles sont prêtes
Orienté développeurs
12. 12
Nouveau modèle de releases
Long Time Support (LTS)
Version tous les 3 ans à partir de Java 11
Le nouveau modèle de support (Oracle JDK)
Pour les clients
Java 9 n’est pas LTS
Ni Java 10
Certains fournisseurs de JDK choisissent uniquement les LTS
Exemple : IBM, Red Hat
Orienté entreprises
13. 13
Mises à jour gratuites ou support payant ?
LTS : maj + support longue durée commercial
Proposé par Oracle selon plusieurs niveaux
Ou par d’autres acteurs (Azul, IBM, Red Hat, …)
Le nouveau modèle de releases remet en cause
Les longues périodes de maj gratuites appliquées jusqu’ici
Entre deux versions de Java (2 à 3 ans) + 1 an d’extension
Période de mises à jour gratuites très courte pour OpenJDK
Uniquement jusqu’à la prochaine feature release (6 mois)
Exemple : plus de mises à jour gratuites pour Java 9 et 10
Amazon Corretto en 2019
LTS avec mises à jour gratuites sans support :
AdoptOpenJDK ??
Patchs de sécurité et critiques uniquement
14. 14
D’autres conséquences
Prévoir aussi des mises à jour des dépendances
Les outils peinent à suivre le rythme
IDE
Outils de build (Maven)
Pour utiliser les nouvelles versions, plus fréquemment diffusées,
il faut mettre à jour les outils plus fréquemment
Choix de la version à utiliser :
pour les développeurs : feature releases ou LTS
pour les entreprises : probablement LTS
Changement de leur rythme de release
Exemple : Eclipse passe en releases trimestrielles
15. 15
Convergence Oracle JDK -> OpenJDK
Depuis une dizaine d’années, Oracle diffuse des JDK
Sous licence Binary Code Licence for Java SE technologies (BCL)
Mixe de termes commerciaux et gratuits
Certaines fonctionnalités requièrent une licence commerciale pour un usage en production
L’objectif atteint est que pour Java 11
OpenJDK et Oracle JDK soient interchangeables
A partir de Java 9, Oracle propose des builds d’OpenJDK
16. 16
Convergence Oracle JDK -> OpenJDK
Avec quelques différences :
taille des livrables car le packaging utilisé est différent
l’option -XX:+UnlockCommercialFeatures (erreur avec OpenJDK)
Les versions affichées sont différentes
A partir de Java 11, Oracle :
ne propose que des JDK pour les serveurs
Plus de JRE
La version gratuite Oracle OpenJDK
est téléchargeable sur le site jdk.java.net
La version commerciale Oracle JDK (à partir de Java 11)
est téléchargeable sur le site d’Oracle
17. 17
Les distributions Java
D’autres fournisseurs proposent aussi des JDK reposant sur OpenJDK
IBM (J9),
Azul (Zulu / Zing),
RedHat,
Des distributions Linux,
Amazon Corretto
…
Le projet AdoptOpenJDK du London JUG
propose des binaires de plusieurs JDK qui passent le TCK
Oracle JDK
Oracle Open JDK
18. 18
Amazon Corretto
Gratuite
Deux versions sont prévues :
Corretto 8 : 1er trimestre 2019, patchs jusqu’en juin 2023
Corretto 11 : 1er semestre 2019, patchs jusqu’en août 2024
JDK reposant OpenJDK utilisé en interne chez Amazon
Preview version 8 annoncée par James Gosling à DevoxxBE
Multi-plateformes, utilisable en production
En local : Amazon Linux 2, Microsoft Windows (versions 7, 10, Server 2008, Server
2012, and Server 2016) et Apple MacOS (version 10.10 Yosemite ou ultérieure)
Avec Docker : une image Docker peut être créée
Dans le cloud : sur Amazon AWS
Et surtout des mises à jour régulières durant une longue période
19. 19
Java 10
12 JEPs
1 utile pour les développeurs
+ évolutions dans les API existantes
6 mois après Java 9, release de Java 10
Diffusé le 20 mars 2018
2 conséquences :
2) Java 9 quasiment pas utilisé
Mais déjà obsolète avec la sortie de Java 10
1) Durée de release réduite -> nombre de fonctionnalités réduites
20. 20
Java 11
6 mois après Java 10, release de Java 11
Diffusé le 25 Septembre 2018 (aujourd’hui)
Java 10 est obsolète et Java 11 est LTS
API
HTTP Client (HTTP/2 + Websockets)
Retirés ou dépréciés
Les modules Java EE et CORBA
Moteur Javascript Nashorn
Pack2000 (outils et API)
…
JVM
Exécution directe d’un fichier Java sans compilation
Support Unicode 10
Flight Recorder
2 GC expérimentaux (ZGC et Epsilon)
Améliorations diverses (NestMates, …)
…
17 JEPs + évolutions dans les API
Langage
var dans les paramètres des Lambdas
Sécurité
support TLS 1.3
algo de cryptage : ChaCha20 et Poly1305
21. 21
La rétrocompatibilité
La sacro sainte rétrocompatibilité
qui a abouti parfois à des choses « particulières »
Ex : les generics, le for évolué, les interfaces fonctionnelles, …
Est partiellement remise en cause, pour plusieurs raisons :
Induit plus de travail de migration
Même si c’est pour la bonne cause
« Dégraisser le mammouth »
JPMS qui renforce l’encapsulation
API retirées du JRE (JAX-B, JAX-WS, Corba, JavaFX, …)
Eléments deprecated retirés (à partir de Java 11)
22. 22
Mise en open source d’outils
La JVM J9 d’IBM -> gérée par la fondation Eclipse
Développement communautaire sous le nom
Peut remplacer une JVM HotSpot dans un OpenJDK
Support commercial d’IBM
https://www.eclipse.org/openj9/
Netbeans d’Oracle -> géré par la fondation Apache
Version 9.0 diffusée cet été
http://netbeans.apache.org/
IBM open source une large partie de Websphere Liberty
Projet Open Liberty
Java EE 7.0 / 8.0 + MicroProfile 1.3
https://openliberty.io/
23. 23
Java EE
N’est plus géré par le JCP
Géré en open source par la fondation Eclipse
Nouveau nom : Jakarta EE
Un travail de reprise titanesque
Les 39 spécifications
La plupart des RI
Les TCK
Un changement de stratégie et de gouvernance
mise en place en cours
Enfin un logo
24. 24
Rachat de Red Hat par IBM
Pour 34 milliards de $
Rachat effectif courant 2019
Fusion de deux géants de l’écosystème Java
Seul l’avenir nous dira les impacts
Pour le moment, Red Hat reste en tant qu’entité à part entière
25. 25
Faut il continuer avec Java ?
Beaucoup se posent la question
Ma réponse est OUI
Malgré une adaptation nécessaire aux changements
Avec une migration longue et délicate
Surtout par rapport aux précédentes
Java a un futur
26. 26
Le futur de Java
Repose beaucoup plus sur la communauté
Travaux sur Java 12 sont en cours
Le futur de Java repose sur une roadmap de grandes fonctionnalités :
Projet Valhalla (JVM)
Nest mate (JEP 181, Java 11)
Value type (JEP 169)
Generic specialization (JEP 218)
Projet Amber (langage)
var (JEP 306, Java 10)
var for Lambda Parameters (JEP 323, Java 11)
Raw String Literals (JEP 326, Java 12 ??)
Switch expression (JEP 325, Java 12 en preview)
Lambda leftover (JEP 302)
Enhanced enums (JEP 301)
Data classes
Pattern matching
Projet Metropolis (JVM)
Java on Java dans la JVM
Projet Loom (concurrence)
Fibers
28. 28
Méthodes private dans les interfaces
Améliorations de la syntaxe
Opérateur diamant dans les classes anonymes internes
Variables effectivement finales dans try with resources
@SafeVarags sur les méthodes d’instances private
L’identifiant _ n’est plus valide
C’est le 51eme mot clé réservé de Java
29. 29
Fabriques pour collection immuable
API et outils
JShell : un outil de type REPL
Process API
Flow API (Reactive Stream)
Var Handles
JavaDoc en HTML 5 avec recherche
Enrichissement de CompletableFuture
30. 30
Globalement de meilleures performances
Améliorations de la JVM
Segmented code Cache
G1 comme GC par défaut
Concaténation des chaînes avec InvokeDynamic
Compact String
Unified JVM Logging
Unified GC Logging
31. 31
Sont perçus comme contraignants
Les modules
Exemple de contraintes :
plus d’accès par défaut aux classes public d’un module
plus d’introspection par défaut sur les classes d’un module
plus de split packages
plus de dépendances circulaires
La nécessité de définir les dépendances dans les module-info ET les outils de build
…
moins de liberté
utilisée pendant plus de 20 ans
parfois avec abus
Tous les systèmes de modules sont contraignants
32. 32
Les modules
Mais on doit profiter des avantages des modules
L’occasion de remettre de l’ordre :
dans le design des livrables
dans les dépendances
dans les API utilisées (notamment celles non supportées du JDK)
Une configuration fiable
Réduire les problèmes du classpath hell
L’encapsulation forte
Améliorer la sécurité et la maintenabilité
Un module est packagé dans un jar modulaire
qui contient un descripteur de module module-info.class
33. 33
4 types de modules
App Named modules Jar modulaire dans le module path
Automatic modules Jar non modulaire dans le module path
Nom extrait de MANIFEST.MF ou dérivé du nom du jar
Tous les packages sont exposés
Peuvent accéder à tous les autres modules
Pont entre named modules et unnamed module
Unnamed module Un seul module
classes, jars modulaires ou non dans le class path
tous les packages sont exposés
Peut accéder à tous les autres modules
Platform modules Modules du JRE
34. 34
Utiliser l’option --describe-module ou –d de l’outil jar
Un jar est il modulaire ?
C:java>jar --file monutil-1.1.jar -d
Descripteur de module introuvable. Module automatique dérivé.
monutil automatic
requires java.base mandated
contains com.oxiane.app.util
C:java>jar -d --file com.oxiane.app.main-1.0.jar
com.oxiane.app.main jar:file:///com.oxiane.app.main.jar/!module-info.class
exports com.oxiane.app.main
requires com.oxiane.app.util
requires java.base mandated
contains com.oxiane.app.common
35. 35
Peuvent être utilisés en simultané
Jars non modulaires et modulaires
peuvent être mis dans l’un ou l’autre
Classpath et module path
Implique des contraintes d’utilisation
Classpath Module path
Jar standard
Unnamed module
Automatic module
Jar modulaire Application named module
37. 37
L’option --illegal-access
Solution temporaire qui sera changée dans une future version
La valeur par défaut sera alors deny
Autoriser ou non les accès par introspection
par le unnamed module
Fait perdre une partie des bénéfices de JPMS
Mais permet d’exécuter plus facilement une application en Java 9
permit affiche un warning à chaque premier accès illégal
Ne pas ignorer ces warnings
Valeur par défaut : permit
qui autorise tous les accès
38. 38
Autres valeurs possibles :
L’option --illegal-access
warning :
Warning à chaque accès
debug :
Warning + informations complémentaires
deny :
Interdire tous les accès
Permet d’anticiper sur le futur
39. 39
JPMS est très strict
Les options pour assouplir JPMS
Parfois bien utile (voire nécessaire) dans certains cas,
Mais il ne faut pas abuser de leur utilisation
--add-modules ajouter des modules au graphe
--add-reads permettre à un module d’accéder à un autre
--add-exports exporter un package d’un module
--patch-module ajouter des classes à un module
--add-opens : permettre un accès par introspection à un package
5 options (javac et jvm) permettent des assouplissements :
Elles ne modifient pas le module-info
40. 40
Etendre le format jar
pour inclure des versions spécifiques de .class pour d’autres versions de Java
dans un même fichier jar
Multi-Release JAR (MR JAR)
Racine du fichier jar
MaClasse.class
META-INF
MANIFEST.MF
versions
9
MaClasse.class
10
MaClasse.class
Un jar peut contenir plusieurs .class pour différentes versions
La version courante à la racine
Les autres versions (>=9), dans META-INF/versions/N
Multi-Release: true dans MANIFEST.MF
Support à partir de Java 9
41. 41
Outil jlink (Java Linker)
Pour créer un JRE personnalisé
Ne contenant que le nécessaire pour l’exécution d’une application
Runtime personnalisé
Déployer facilement une application
Sans s’appuyer sur un JRE pré-installé
Tous les jars doivent être modulaires
Uniquement des named modules (pas d’automatic modules)
Incluant TOUTES les dépendances
Tous les jars doivent être modulaires
Uniquement des named modules (pas d’automatic modules)
Incluant TOUTES les dépendances
Besoin de créer un JRE par environnement
Nécessiter de recréer un JRE pour le mettre à jour
43. 43
Java 10 repose sur Java 9
Java 10
Avec des corrections et évolutions mineures
12 JEPs :
286: Local-Variable Type Inference
304: Garbage-Collector Interface
307: Parallel Full GC for G1
310: Application Class-Data Sharing
312: Thread-Local Handshakes
319: Root Certificates
296: Consolidate the JDK Forest into a Single Repository
313: Remove the Native-Header Generation Tool (javah)
314: Additional Unicode Language-Tag Extensions
316: Heap Allocation on Alternative Memory Devices
317: Experimental Java-Based JIT Compiler
322: Time-Based Release Versioning
Une release tous les 6 mois -> une release plus petite
44. 44
Depuis Java 7, l’inférence de type est de plus en plus utilisée
L’inférence de type des variables locales
Avec Java 10 : pour faciliter la déclaration de variables locales
for (var i = 0; i < 10; i++) { ... }
for (var arg : args) { ... }
try (var file = new FileInputStream(new File("monfichier.txt"))) { ... }
var est utilisable dans les boucles et try with resources
var i = 2; // int
var j = 2L; // long
var var = "Bonjour"; // String
var references = new HashMap<Integer,String>(); // HashMap<Integer,String>
var chemin = Paths.get("fichier.txt"); // Path
var contenu = Files.readAllBytes(chemin); // byte[]
var objet = new Serializable() {} ; // MaClasse$1
Avec l’instruction var
Qui n’est pas un mot clé
45. 45
L’inférence de type des variables locales
Plusieurs situations sont illicites
var valeur; // cannot use 'var' on variable without initializer
var obj = null; // variable initializer is 'null'
var a=1, b=2; // 'var' is not allowed in a compound declaration
// var a=1; var b=2;
var chaines = {"e1","e2"}; // array initializer needs an explicit target-type
// var chaines = new String[] {"e1","e2"};
var additionner = (a,b) -> a+b; // lambda expression needs an explicit target-type
// var additionner = (IntBinaryOperator) (a,b) -> a+b
var comparerStr = String::compareTo; // method reference needs an explicit target-type
// var comparerStr = (Comparator<String>) String::compareTo
var valeur = 10;
valeur = "bonjour"; // incompatible types: String cannot be converted to int
// Java n’est pas Javascript et reste statiquement typé
Incompatibilité
jshell> class var {}
| Error:
| 'var' not allowed here
| as of release 10, 'var' is a restricted local variable type and cannot be used for type
declarations
46. 46
L’inférence de type des variables locales
Utiliser var avec discernement
le code peut être plus ou moins lisible (surtout sans IDE)
Importance accrue du nom des variables
l’abstraction est limitée : pas d’inférence vers un super type ou une interface
le type inféré est ArrayList<String>
List<String> aurait été préférable
jshell> var liste = new ArrayList<String>();
liste ==> []
jshell> liste.trimToSize()
jshell>
jshell> List<String> liste2 = new ArrayList<>();
liste2 ==> []
jshell> liste2.trimToSize()
| Error:
| cannot find symbol
| symbol: method trimToSize()
| liste2.trimToSize()
| ^---------------^
47. 47
Optional, OptionalInt, OptionalLong, OptionalDouble
orElseThrow() : alternative à get()
Mises à jour des API
java.util.stream.Collectors
toUnmodifiableList()
toUnmodifiableSet()
toUnmodifiableMap(Function, Function)
toUnmodifiableMap(Function, Function, BinaryOperator)
List, Set, Map
static copyOf(Collection) : copie immuable de la collection
48. 48
Support de Docker
Java 10 : Meilleur support des conteneurs Docker
JDK-8189497 et JDK-8186315, JDK-8179498, JDK-8186248, JDK-8146115
Option UseContainerSupport (Linux uniquement)
activée par défaut, -XX:-UseContainerSupport pour désactiver
Extraction d’informations du conteneur (cgroup)
nombre de CPU alloué au conteneur
mémoire allouée au conteneur
Détection de l’exécution dans un conteneur
49. 49
Java 8u131 et Java 9
-XX:+UnlockExperimentalVMOptions (Linux uniquement)
-XX:+UseCGroupMemoryLimitForHeap (Linux uniquement)
-XX:InitialRAMFraction, -XX:MaxRAMFraction, -XX:MinRAMFraction (1, ½, 1/3, ¼, …)
Support de Docker
Java 10 :
Ajout de :
-XX:InitialRAMPercentage=n
-XX:MaxRAMPercentage=n
-XX:MinRAMPercentage=n
-XX:ActiveProcessorCount=n
-Xlog:os+container
Deprecated
-XX:+UseCGroupMemoryLimitForHeap
-XX:MaxRAMFraction
-XX:InitialRAMFraction
-XX:MaxRAMFraction
Options pour le contrôle de la mémoire
51. 51
Sans var le type est toujours inféré par le compilateur
var dans les paramètres des Lambdas
Plusieurs situations illicites :
Avec var le type est inféré de la même manière
(a, b) -> a.executer(b)
(var a, var b) -> a.executer(b)
L’intérêt est de pouvoir utiliser des annotations ou des modificateurs
Impossible sans le type explicite ou var
(@Nonnull var a, var b) -> a.executer(b)
(var a, b) -> a.traiter(b)
// (cannot mix 'var' and implicitly-typed parameters)
(var a, int b) -> a.traiter(b)
// (cannot mix 'var' and explicitly-typed parameters)
var a -> a.traiter()
// ';' expected
// les parenthèses sont obligatoires avec var et un seul paramètre
52. 52
S’enrichit de nouvelles méthodes
Avec une nouvelle gestion des caractères considérés comme des espaces
Définit dans la nouvelle méthode Character.isWhiteSpace(int)
La classe String
String strip() / stripLeading() / stripTrailing()
Retirer les espaces en début et/ou fin de chaîne
boolean isBlank()
Indique si la chaîne est vide ou ne contient que des espaces
Steam<String> lines()
Obtenir un Stream dont les éléments sont chaque lignes de la chaîne
Le découpage repose sur le séparateur de lignes n
String repeat(int count)
Répéter la chaîne le nombre de fois précisé en paramètre
53. 53
API cliente pour requêtes HTTP
But : remplacer HttpURLConnection
Support HTTP version 1.1 et 2 ainsi que les WebSockets
Modèle de programmation synchrone et asynchrone
Utilisation du pattern builder
Gestion du body des requêtes et réponses avec Reactive streams
L’API HTTP Client
Java 9
Dans le module incubator jdk.incubator.httpclient
Ajout du module au graphe avec --add-modules
Package jdk.incubator.http
Java 10
Ajout de BodyPublisher et BodySubscriber
Java 11
Dans le module java.net.http, package java.net.http
54. 54
Obtenir une instance de HttpClient
En utilisant la fabrique newHttpClient()
L’API HTTP Client
ou un HttpClient.Builder
HttpClient client = HttpClient.newHttpClient();
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.followRedirects(Redirect.NORMAL)
.proxy(ProxySelector.of(new InetSocketAddress("proxy.oxiane.com", 80)))
.authenticator(Authenticator.getDefault())
.build();
55. 55
Créer une instance de HttpRequest
Grâce à un HttpRequest.Builder obtenu avec la fabrique newBuilder()
L’API HTTP Client
Ou un HttpRequest.Builder pour configurer la requête
Pour un POST ou un PUT, le body est fourni grâce à un BodyPublisher
La classe BodyPublishers propose des fabriques pour des usages courants
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://www.oxiane.com")).build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://www.oxiane.com"))
.POST(HttpRequest.BodyPublishers.ofString("nom=test"))
.build();
56. 56
La réponse de la requête est encapsulée dans un HttpResponse
Le contenu du body de la réponse est obtenu via un BodyHandler
La classe BodyHandlers propose des fabriques pour des usages courants
L’API HTTP Client
La requête peut être envoyée de manière synchrone
De manière synchrone grâce à la méthode send() de HttpClient
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
De manière asynchrone grâce à la méthode sendAsync() de HttpClient
Elle retourne un CompletableFuture<HttpResponse<T>> pour traiter la réponse
57. 57
Exécution d’un fichier source Java directement par la JVM
Sans compilation
Exécution d’un fichier Java
Le fichier .class ne doit pas exister
Sous Linux
Utilisation possible d’un fichier Shebang
Rendu exécutable (chmod +x)
C:java> type Hello.java
public class Hello {
public static void main(String... args) {
System.out.println("Hello");
}
}
C:java> java Hello.java
Hello
C:java> dir Hello*
Répertoire de C:java
25/03/2017 00:29 109 Hello.java
1 fichier(s) 109 octets
#!/usr/java/11/bin/java --source 11
public class Hello {
public static void main(String... args) {
System.out.println("Hello");
}
}
58. 58
Implémentation de certaines fonctionnalités de TLS version 1.3
Spécifications publiées en mars 2018
Support TLS 1.3
TLS 1.3 propose :
Améliorations de la sécurité
Retrait de l’utilisation d’algorithmes obsolètes : MD5, RC4, DES, 3DES, DSA, SHA-224
Au profit de plus récents : ChaCha20, Poly1305, Ed25519, x448, x25519
Améliorations de la performance
Négociations plus rapides
Une incompatibilité avec les versions précédentes
Pas de nouvelle API, implémentation dans JSSE
Nom du protocole à utiliser : TLSv1.3
59. 59
Ramasse-miettes expérimentaux sous Linux x64 uniquement
Leur utilisation requiert l’option -XX:+UnlockExperimentalVMOptions
ZGC et Epsilon
ZGC
Permet une montée en charge tout en gardant une faible latence (<10ms)
Sur des heaps de très très grandes tailles (plusieurs To)
Activation avec l’option -XX:+UseZGC
Epsilon
N’implémente aucune fonctionnalité pour récupérer de la mémoire
Utilité : tests de performance, application à durée de vie courte
Activation avec l’option -XX:+UseEpsilonGC
60. 60
Capturer des infos de la JVM dans un fichier avec un faible overhead
pour aider à diagnostiquer des anomalies
Flight recorder
Activation avec l’option -XX:StartFlightRecording
Fourni dans Oracle JDK
Avec utilisation commerciale en production
Maintenant intégré dans OpenJDK
Activation avec jcmd
jcmd <pid_jvm> JFR.start
jcmd <pid_jvm> JFR.dump filename=fichier.jfr
jcmd <pid_jvm> JFR.stop
// enregistrement dans un fichier durant 1 minute après avoir attendu 30 secondes
java -XX:StartFlightRecording=delay=30s,duration=60s,filename=monapp.jfr,
settings=profile,name=MonAppRecording MonApp
62. 62
Java 9 enrichit l’annotation @Deprecated
Enhanced deprecation
String since() :
version à partir de laquelle l’élément annoté est déprécié
"" par défaut
boolean forRemoval() :
prévue pour être retirée dans le futur
false par défaut
Nouvel outil jdeprscan
Pour rechercher les API dépréciées utilisées
63. 63
Nouvel outil de Java 9
Analyse statique des .class pour rechercher les API deprecated
jdeprscan
On n’y est pas habitué
Il y a des API deprecated depuis Java 1.1
Notamment les API deprecated for removal
Important car elles seront retirées
Dans un futur plus ou moins proche
jdeprscan xxx-3.0.7.jar
Jar file xxx-3.0.7.jar:
class xx/xxx/XxxxXxx uses deprecated class javax/security/cert/X509Certificate
class xx/xxx/XxxxXxx uses deprecated method java/lang/Object::finalize()V
class xx/xxx/XxxxXxx$1 overrides deprecated method java/lang/Object::finalize()V
class xx/xxx/XxxxXxx uses deprecated class javax/security/cert/CertificateException
64. 64
En Java 9, l’API Applet est dépréciée
java.applet.AppletStub, java.applet.Applet, java.applet.AudioClip,
java.applet.AppletContext, javax.swing.Japplet
L’outil appletviewer
Applet et Java Web Start
Remarque : l’API n’est pas retirée pour le moment
Le support du plug-in par les navigateurs est retiré
Ou le retrait est planifié
Java Web Start et le protocole JNLP sont
dépréciés en Java 9
retirés en Java 11
65. 65
Avec Java 11
Nashorn, Java FX, SNMP
Comme annoncé par Oracle début 2018, Java FX est retiré du JRE
Les modules javafx.* sont retirés
Il faut ajouter les modules de Java FX au module path comme toutes autres dépendances
JavaFX devient un projet open source géré par la communauté OpenJFX
Un support commercial dans Oracle JDK 8 est proposé jusqu’en 2022
La JEP 335: Deprecate the Nashorn JavaScript Engine
Déprécie le moteur d’exécution JavaScript Nashorn
Ajouté en Java 8
Le support de SNMP est retiré
Pack2000 (Outils et API) est déprécié
66. 66
Les modules Java EE
Les modules Java EE ne sont pas résolus par défaut
• java.activation (JAF)
• java.corba (CORBA)
• java.transaction (JTA)
• java.xml.bind (JAX-B)
• java.xml.ws (JAX-WS et SAAJ)
• java.xml.ws.annotation (Commons annotations)
Le module java.se.ee regroupe ces 6 modules
Plus 2 modules du JDK
• jdk.xml.ws (outils pour JAX-WS : wsgen, wsimport)
• jdk.xml.bind (outils pour JAXB : xjc, schemagen)
Ils sont deprecated for removal en Java 9
Ils sont retirés du JDK en Java 11
67. 67
De Java 9
jhat
Outil expérimental fourni avec Java 6
D’autres outils de visualisation du heap sont disponibles
Java DB
Base de données Apache Derby
Fournie avec les JDK 7 et 8 dans le sous-répertoire db
JVisualVM
A télécharger https://visualvm.github.io/
native2ascii
Les outils retirés
De Java 10
javah
Remplacé par l’option -h de javac
policytool
68. 68
De Java 11
appletviewer
javaws
Les outils de JAX-WS et JAX-B
schemagen
wsgen
wsimport
xjc
jmc (Java Mission Control)
Devenu un projet open source http://openjdk.java.net/projects/jmc/
Renommé en JDK Mission Control
Les outils retirés
69. 69
Faire un état
des lieux
avant migration
Faire un état
des lieux
avant migration
70. 70
Recenser les différents points à prendre en compte
Utilité
Aider à choisir la stratégie de migration
Avoir une meilleure visibilité sur l’ampleur de la tâche
Faire une cartographie des dépendances
Vérifier pour chacune si une version modulaire existe
En profiter pour faire du ménage
Et prévoir des upgrades
Utiliser l’outil jdeps pour obtenir des informations
71. 71
Fournit dans le JDK depuis Java 8, amélioré en Java 9
jdeps
Analyse statique du bytecode pour déterminer les dépendances
Travaille sur les .class ou .jar
A passer sur l’application
mais aussi sur toutes les dépendances
Pour obtenir de nombreuses informations :
Des dépendances
Les split packages
Les API du JDK qui ne sont plus accessibles
72. 72
jdeps
Dépendances agrégées au niveau des packages ou des jars
Possibilité de filtrage
Différents formats de restitution
dont des fichiers .dot
Par défaut affiche :
les modules du JDK requis
les dépendances de chaque packages
<package> -> <package> <module/JAR>
73. 73
Nombreuses options : -h pour l’intégralité
Les options de jdeps
jdeps --class-path 'libs/*' -recursive monapp-3.2.jar
Option Rôle
--class-path ou -cp définir les dépendances dans le classpath
--module-path définir les dépendances dans le module path
-recursive ou –R parcours récursif des dépendances
--package ou –P seulement les dépendances vers un package
--dot-ouput créer des fichiers .dot par jar utilisable avec GraphViz
-verbose:class dépendances entre classes
--summary ou –s afficher un résumé des dépendances
--generate-module-info générer le fichier module-info.java
--generate-open-info générer le fichier module-info.java pour un module open
--jdk-internals ou -jdkinternals trouver les API internes utilisées
75. 75
Deux stratégies :
Migrer une bibliothèque
Sans conversion en module
Il faut absolument figer le nom du module
avec l’attribut Automatic-Module-Name dans le fichier MANIFEST.MF
Sinon le nom du module est déterminé à partir du nom du jar -> automatic module
Ne DOIT pas changer lors de la modularisation
La conversion en module d’un jar
Ajout d’un fichier module-info
fixe le nom du module et les dépendances
Permet son utilisation dans le module-path
et donc de le déclarer comme dépendance d’un autre module
Permet toujours son utilisation via le classpath
Toujours tester dans le classpath et le module path
76. 76
Différentes stratégies :
Migration d’une application
Pas de migration
Migration vers une autre techno
Attente de la prochaine LTS
Migration vers les modules
Avec prise en compte du nouveau modèle de release
Migration sans les modules
Migration incrémentale
77. 77
Il y a encore (de rares) applications qui tournent en Java 4/5 (2004)
Pas de migration
Attention : plus de mises à jour gratuites de Java 8
Pour profiter des corrections, des nouvelles fonctionnalités dans la JVM
Et surtout plus de mises à jour relatives à la sécurité (cf RGPD)
et/ou la performance
Un peu plus en Java 6 (2006) et beaucoup en Java 7 (2011)
Pas de migration = rester en Java 8
Plus de support gratuit d’Oracle à partir de janvier 2019 (grâce à une extension d’Oracle)
Grosses difficultés / impossibilité d’upgrader les dépendances
78. 78
Coût de réécriture et de test
surtout pour de grosses applications
Migration vers autre techno
Quel est le R.O.I. notamment pour le back end ?
Choix de la techno ?
Php / ROR
.Net
JavaScript / Node.JS
Scala, Kotlin
….
79. 79
Stratégie viable
puisque cela laisserait entre 2 et 3 ans pour migrer
Attente de la prochaine LTS
Vrai, sans le nouveau modèle de releases
La prochaine version LTS : Java 11 (25 septembre 2018)
Le support public de Java 8 est étendu à janvier 2019
2020 pour un usage personnel
http://www.oracle.com/technetwork/java/eol-135779.html
80. 80
LA solution cible
qui ne repose que sur des modules
Migrer vers les modules
N’utilise que des modules :
Plateform modules (JRE)
Et named modules (applications et toutes les dépendances)
Ajouter un module-info à chaque jar
Tenir compte de certaines contraintes et difficultés
Souvent compliqué et parfois impossible directement
Notamment à cause des dépendances (en particulier les transitives)
81. 81
Il est possible de n’utiliser que le classpath
Comme avant Java 9
Migrer sans les modules
Attention :
le JRE est modulaire
Permet une exécution en Java 9,
généralement non sans certaines adaptations
Prendre en compte certaines contraintes
82. 82
Le JDK est modulaire
Migration incrémentale
Certains modules peuvent coopérer avec les jars non modulaires
=> Nécessité de cohabitation
entre jars modulaires et non modulaires
L’application peut être modularisée
partiellement
ou intégralement
ou pas
Les dépendances ne sont pas toutes modulaires
83. 83
Migration incrémentale
Plusieurs fonctionnalités facilitent cette cohabitation :
L’option --illegal-access par défaut à permit
Les options pour assouplir les règles de JPMS
Multi-Release JAR
Facilitée par la coexistence du classpath et du module path
=> Migration incrémentale sera généralement la stratégie utilisée
85. 85
L’identifiant _ n’est plus valide
Les incompatibilités
Alignement de la structure des répertoires du JDK et JRE
Fonctionnalités de la JVM retirée
Les fichiers rt.jar et tools.jar
Le mécanisme d’extension
Le mécanisme endorsed
86. 86
La plupart des API internes sont encapsulées
et ne sont donc plus accessibles
Les API internes
Ces API sont non standard / non supportées
Elles n’auraient jamais dû être utilisées
Certaines sont remplacées
Ex : sun.misc.BASE64Decoder
Certaines sont encore accessibles
En attendant leur remplacement
Ex : sun.misc.Unsafe (partiellement remplacée par Var Handles)
87. 87
Les API internes
Utiliser jdeps avec l’option --jdkinternals
MaClasse.class -> JDK removed internal API
MaClasse -> sun.misc.BASE64Encoder JDK internal API (JDK removed internal API)
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.BASE64Encoder Use java.util.Base64 @since 1.8
Utiliser --illegal-access=deny pour simuler le futur
88. 88
Des jars non modulaires peuvent avoir des dépendances cycliques
Ce n’est pas une bonne pratique
Mais on en trouve dans le classpath
Les dépendances cycliques
Cela peut donc compliquer la migration
Les modules NE peuvent PAS avoir de dépendances cycliques
A la compilation ou à l’exécution
89. 89
Packages présents dans plusieurs jars
Split packages
Pour des raisons de compatibilité :
les split packages sont autorisés dans l’unnamed module
avec des contraintes
JPMS interdit les split packages dans les modules
Pour assurer la fiabilité de la configuration
S’applique pour les packages dans les modules
des modules exportés ou NON
Courant dans le classpath
91. 91
Les modules Java EE ne sont pas résolus par défaut
JAX-B, JAX-WS, JavaBeans Activation Framework, JTA, Commons annotations, CORBA
Les modules Java EE
• java.activation (JAF)
• java.corba (CORBA)
• java.transaction (JTA)
• java.xml.bind (JAX-B)
• java.xml.ws (JAX-WS et SAAJ)
• java.xml.ws.annotation (Commons annotations)
Le module java.se.ee regroupe ces 6 modules
Plus 2 modules du JDK
• jdk.xml.ws (outils pour JAX-WS : wsgen, wsimport)
• jdk.xml.bind (outils pour JAX-B : xjc, schemagen)
Ils sont deprecated for removal en Java 9
92. 92
Il faut obligatoirement utiliser une tierce dépendance
Les modules Java EE
Ils sont retirés dans Java 11
JAF Automatic-Module-Name: java.activation
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
JTA
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.3</version>
JAX-B nom du module java.xml.bind
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.4.0-b180830.0359</version>
JAX-WS
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.0.2</version>
<type>pom</type>
CORBA
???
Common annotations Automatic-Module-Name:
java.annotation
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
93. 93
Dépendances utilisées à l’exécution uniquement si présente
Exemple : une implémentation d’un cache
Les dépendances optionnelles
Solution 2 :
Utiliser un service pour découpler consommateur et fournisseur
Fournisseur :
provides xxx with yyy dans le module-info
Consommateur :
uses xxx dans le module-info
Utiliser l’API ServiceLoader pour charger la classe
Solution 1 :
requires static dans le module-info
Utiliser l’introspection pour créer des instances de manière défensive
94. La version est parfois utilisée pour de mauvaises raisons
Nouveau format de version
Solution :
Utiliser l’API Runtime.Version
Utiliser MR JAR
Le format de version change de nouveau en Java 10
Rechercher du code qui parse le numéro de version
Pas évident car aucune API standard
Le format de la version de Java 9 change
96. 96
Conclusion
Java évolue, nous devons (devrons) suivre
Téléchargez Java 11 et essayez
Tout en tenant compte des évolutions
Notamment le nouveau modèle de releases
La migration vers les modules (JPMS) sera obligatoire
tôt ou tard
Elle va être délicate et longue
en tout cas plus longue et délicate que pour les précédentes versions