#ParisJUG 1
Java en 2022 :
profiter de Java 17
JMdoudouX
#ParisJUG
Java a évolué sur la décade
2
• Avec pas moins de 10 versions publiées
grâce au nouveau modèle de releases
• Avec un accueil partagé/mitigé selon les versions
qui sont passés par différentes couleurs de l’arc en ciel
• Trois versions LTS
Java 10, 12, 13, 14, 15, 16 : transparence
Java 8 : fort engouement
Java 11 : adoption (très) lente
Java 17 : bonheur des devs
• Sept versions non-LTS
Java 9 : a cassé l’engouement
#ParisJUG
Quelle version utilisez vous en prod ?
3
• Java 17
• Java 11
• Java 8
• Java 7
• Java < 7
#ParisJUG 4
Jean-Michel Doudoux
http://www.jmdoudoux.fr
@jmdoudoux
Co-fondateur du , membre du
Auteur de 2 didacticiels
Diffusés sous licence GNU FDL
• Développons en Java (4001 pages)
• Développons en Java avec Eclipse
CTO et
#ParisJUG
Roadmap
5
• Le présent
• La migration vers Java 11 et 17
• Convaincre l’exploitation
• Le futur
• Le passé
• 10 ans d’évolutions de Java
• Convaincre le management
• Mettre en œuvre la migration
#ParisJUG
10 ans d’évolutions
de Java
#ParisJUG
2012
7
• La version courante est Java 7 (juillet 2011)
• NIO 2
Path, Files, Glob, WatchService, DirectoryStream, walkFileTree() …
• Des APIs requises pour Java 8 : fork/join, invoke dynamic
• Le projet Coins
try with resources, exceptions multiples dans catch, opérateur diamant,
String dans switch, underscore dans les littéraux numériques
long valeur = 10_000_000_000L;
long valeur = 1_0_0_0_0_0_0_0_0_0_0L;
#ParisJUG
Java 8
8
• Sortie en mars 2014
• Les expressions Lambda et les références de méthode
• Une approche fonctionnelle du traitement de données
avec l’API Stream
• L’API Date & Time
• Redonne un fort engouement pour Java
• Les méthodes par défaut et static dans les interfaces
• Les classes Optional
• Les annotations répétées
#ParisJUG
Java 9 : syntaxe
9
• Evolutions mineures dans le langage
@SafeVarags sur des méthodes privées
l’opérateur diamant sur les classes anonymes
try with resources : utilisation directe de variables explicitement final
le caractère _ (underscore) est un mot clé réservé
les méthodes privées dans les interfaces
// Java 7 et 8
public void lire(FileInputStream fis) {
try(FileInputStream fisr = fis) {
// ...
}
// Java 9
public void lire(FileInputStream fis) {
try(fis) {
// ...
}
• Sortie en septembre 2017
#ParisJUG
Java 9 : API /Outils
10
• JShell : outil de type REPL
tester une portion de code ou expérimenter une API
• API Process
interface ProcessHandle
• Fabriques statiques pour collections immuables
• Stackwalking API
• Flow API (Reactive Streams)
• VarHandle
opérations atomiques/ordonnées via une référence typée à une variable
List<String> lettres = List.of("a", "b", "c", "d");
#ParisJUG
Java 9 : les modules
11
• Les principaux objectifs proposent d’améliorer :
la fiabilité de la configuration (reliable configuration)
la sécurité avec l’encapsulation forte (strong encapsulation)
la performance
la maintenabilité
• La fonctionnalité la plus impactante … et la plus controversée
• La mise en œuvre implique des contraintes
ruptures (visibilité, accessibilité, organisation du code, …)
• Solutions pour faire cohabiter monde modulaire et non modulaire
• Rendre modulaire une application n’est pas obligatoire
• Création de JRE personnalisés
via l’outil jlink
#ParisJUG
L’instruction var(Java 10)
12
• Pour faciliter la définition de variables var salutation = "Bonjour";
var bonneChancePourNommerCetteVariable = personnes.stream().collect(...)))))));
var service = new Object() {
void afficher() {}
void calculer() {}
};
service.calculer();
service.afficher();
• Le type inféré est parfois surprenant var liste = List.of("test",1);
List<Serializable & Comparable<? extends Serializable & Comparable<?>>>
En Java 11
List<Serializable & Comparable<? extends Serializable & Comparable<?> &
java.lang.constant.Constable & java.lang.constant.ConstantDesc> &
java.lang.constant.Constable & java.lang.constant.ConstantDesc>
En Java 17
• Nouvelles opportunités
avec les classes anonymes
Map<Integer, Map<String, Map<String, Map<Integer, List<Personne>>>>>
bonneChancePourNommerCetteVariable = personnes.stream.collect(...)))))));
var var = personnes.stream().collect(...)))))));
#ParisJUG
Support des conteneurs
13
• Bien meilleur support en Java 10
• Détection de l’exécution dans un conteneur Docker
• Backport en Java 8u191
• Prise en compte des limitations de ressources (cgroups)
• Options plus fines pour la gestion de la mémoire
Brice et
J-Philippe
#ParisJUG
Java 11
14
• Diffusée en septembre 2018
• Version importante car LTS
• Exécution directe d’un unique fichier .java par la JVM
sans compilation préalable
• API HTTP Client
support HTTP 1.1 et 2, websockets, synchrone/asynchrone
• JDK Flight Recorder
#ParisJUG
Switch expressions(Java 14)
15
switch (niveau) {
case 1, 2 -> {
System.out.print("Débutant");
System.out.println(" et junior");
}
case 3, 4 -> System.out.println("Confirmé");
case 5 -> System.out.println("Expert");
}
String libelle = switch (niveau) {
case 1, 2 -> "Débutant";
case 3, 4 -> "Confirmé";
case 5 -> "Expert";
default -> {
System.out.println("cas par défaut");
yield "Non défini";
}
};
System.out.println(libelle);
String libelle = switch (niveau) {
case 1, 2 : yield "Débutant";
case 3, 4 : yield "Confirmé";
case 5 : yield "Expert";
default : {
System.out.println("cas par défaut");
yield "Non défini";
}
};
System.out.println(libelle);
switch (niveau) {
case 1, 2 :
System.out.print("Débutant");
System.out.println(" et junior");
break;
case 3, 4 :
System.out.println("Confirmé");
break;
case 5 :
System.out.println("Expert");
break;
}
#ParisJUG
Blocs de texte(Java 15)
16
• Exprimer une chaîne de caractères littérale multiligne
simplement : basiquement sans séquence d’échappement
• Gestion de l’indentation accessoire/significative en début et fin
en déplaçant le contenu vers la droite
en déplaçant le délimiteur de fermeture vers la gauche
• 2 nouveaux caractères d’échappement
s pour indiquer un espace
<retour_chariot> supprime la fin de ligne
String html = """
<HTML>
<BODY>
<H1>"Hello"</H1>
</BODY>
</HTML>""";
String html = """
<HTML>
<BODY>
<H1>"Hello"</H1>
</BODY>
</HTML>""";
String html = """
<HTML>
<BODY>
<H1>"Hello"</H1>
</BODY>
</HTML>
""";
#ParisJUG
Helpful NullPointerException (Java 15)
17
• On rencontre fréquemment des exceptions de type NPE
• Hormis la stacktrace, pas d’informations utiles
• JVM réalise une analyse du byte-code
pour fournir un message d’erreur utile sur une NPE (conséquence, cause)
d’autant plus précis avec info de débogage (-g du compilateur)
• Le message fourni est contextuel
C:java>javac -g TestNPE.java
C:java>java TestNPE
Exception in thread "main" java.lang.NullPointerException: Cannot invoke
"String.toUpperCase()" because "message" is null
at TestNPE.main(TestNPE.java:5)
#ParisJUG
Pattern matching pour instanceof
(Java 16)
18
• Pour simplifier le code
• Utilisation de l’opérateur &&
if (obj instanceof Groupe) {
Groupe groupe = (Groupe) obj;
var membres = groupe.membres();
}
if (obj instanceof Groupe groupe) {
var membres = groupe.membres();
}
if (obj instanceof Groupe groupe && !groupe.membres().isEmpty()) {
System.out.println(groupe.membres());
}
#ParisJUG
Les records(Java 16)
19
• Un nouveau type pour définir une classe
• Encapsulant des données de manière immuable
• Avec une syntaxe concise
utilisant l’identifiant restreint record
• Un record peut être personnalisé
avec un constructeur compact
public record Formation(String titre, String code, Duration duree) {
}
public record Formation(String titre, String code, Duration duree) {
public Formation {
if (titre.isBlank()) {
throw new IllegalArgumentException("Le titre doit être renseigné");
}
}
}
#ParisJUG
Les records(Java 16)
20
• Possibilité de définir et utiliser des records locaux
implicitement static
• Mais aussi des interfaces et énumérations locales (Java 15)
• Les records sont immuables au sens Java
• Les records sont « vraiment » immuables
il n’est pas possible de modifier la valeur/référence d’un composant
même en utilisant l’API Reflection ou VarHandle
• La désérialisation d’un record est différente
elle invoque le constructeur canonique
#ParisJUG
Les classes scellées (Java 17)
21
• Fonctionnalité standard pour restreindre par déclaration
les classes qui peuvent étendre une classe scellée
les classes qui peuvent implémenter une interface scellée
• But : connaître de manière exhaustive les sous-types
• 3 nouveaux mots-clés contextuels : sealed, non-sealed et permits
• Les classes filles doivent avoir un des modificateurs
final, sealed ou non-sealed
• 2 contraintes sur l’endroit où pourront être les classes filles
dans un module nommé : dans le même module que leur classe mère
dans un unnamed module : dans le même package que leur classe mère
public sealed class Forme permits Cercle, Triangle {}
#ParisJUG
Java 17
22
• Diffusée en septembre 2021
• Nouvelle version majeure car LTS
• Le Security Manager est déprécié forRemoval
• Oracle diffuse son JDK sous licence NFTC
No-Fee Terms and Conditions
• Réduction de la durée entre 2 LTS à 2 ans
#ParisJUG
Java 18
23
• Diffusée en mars 2022
• UTF-8 par défaut (sauf sortie console)
• Le mécanisme finalize est déprécié
• Les extraits de code dans la Javadoc avec @snippet
• Un serveur web minimaliste
• Des améliorations dans les ramasse-miettes et la sécurité
#ParisJUG
Bilan de ses évolutions
24
• Souvent la verbosité est reprochée à Java
• Java se modernise et se simplifie
• Les évolutions présentées ne sont que les principales
• Il y en a beaucoup d’autres :
Collector teeing (Java 12)
jpackage (java 16)
hidden class (Java 15)
default et dynamic CDS archive (Java 12 et 13)
Stream::toList() (Java 16)
java.text.CompactNumberFormat (Java 12)
…
#ParisJUG
Le présent
Migration
#ParisJUG
Le plus dur reste à faire
26
• Maintenant que vous être convaincus
• Le plus dur reste à faire
• Convaincre l’exploitation
• Pour migrer vers une LTS plus récente : Java 11 ou 17
• Et donc budgéter et planifier cette migration
… et le management
#ParisJUG
Migration
Convaincre l’exploitation
#ParisJUG
Utiliser les évolutions vues
28
• Pour nous dev, beaucoup de choses sympa
• dans la syntaxe
• dans les API
• Mais malheureusement peu recevables
d’un point de vue exploitation
• Surtout que pour de (bonnes) raisons, elle est conservatrice
#ParisJUG
Les arguments recevables
29
• Les devs focalisent beaucoup sur la syntaxe et les API
• Mais l’élément majeur de Java c’est la JVM
• La JVM évolue aussi notamment sur
• La performance
• Et la sécurité
• Deux préoccupations majeures de l’exploitation
#ParisJUG
Performance
30
• La JVM de chaque version LTS améliore les performances
de manière globale
dépend du type d’application et de son activité
• Les ramasse-miettes évoluent
tous, G1 par défaut sur JVM server (Java 9)
• Et de nouveaux sont ajoutés :
ZGC, Shenandoah, Epsilon GC
• Le JIT
• Des optimisations dans les implémentations des API
compact String (Java 9), …
• Ça fonctionne bien en Java 8 -> encore mieux en 11 ou 17
#ParisJUG
Sécurité
31
• Maj Root CA Certificates et algo faibles désactivés
• Support de TLS 1.3 (Java 11)
• Algo de cryptographie :
ChaCha20 et ChaCha20-Poly1305 (Java 11)
Edwards-Curve Digital Signature Algorithm (EdDSA) (Java 15)
• PKCS12 par défaut dans le keystore (Java 9)
• SHA-3 (Java 9)
• Support de TLS 1.0 et 1.1 retirés (Java 16)
• Filter Incoming Serialization Data (Java 9)
Context-Specific Deserialization Filters (Java 17)
Charles
#ParisJUG
Migration
Convaincre le management
#ParisJUG
Les coûts
33
• Très variables pour la migration selon l’état de l’application
surtout avec les tests
• De la version courante (8 / 11) et ciblée de Java (11 / 17)
• Les performances peuvent réduire les coûts d’exploitation
surtout dans le cloud
GCs qui restituent la mémoire inutilisée au système
compact Strings (économie de heap)
jlink pour des runtimes personnalisés
….
#ParisJUG
D’autres arguments
34
• Très difficile de recruter actuellement
• Encore plus sur des technologies obsolètes
• Migrer pour être sur un socle plus récent, peut faciliter
• Mais aussi pour limiter le turn over
• Car au final le coût est parfois supérieur à celui de la migration
• Et puis … la RGPD pour un aspect légal
#ParisJUG
Migration
Mise en œuvre
#ParisJUG
Règles générales de migration > 8
36
• Mettre à jour les outils
avec une version compatible avec la version de Java ciblée
• Mettre à jour les dépendances
avec une version compatible avec la version de Java ciblée
• Utiliser jdeps (sur app et toutes les dépendances) pour
une cartographie des dépendances
les API internes utilisées
détecter les splits packages
• Mythe urbain : aucune obligation de modulariser l’application
migrer en laissant tout dans le classpath
modulariser si possible
#ParisJUG
Des API retirées
37
• A partir de Java 11, toutes les versions de Java retirent des API
• Celles marquées dans la ou les versions précédentes avec
• Consultez les listes de différences entres versions de Java
https://javaalmanac.io/
https://foojay.io/almanac/java-17/
• Utilisez jdeprscan pour obtenir les API dépréciées du JDK
à utiliser sur tout le classpath et modulepath
@Deprecated(forRemoval=true)
#ParisJUG
Java 8 vers 11
38
• Régler les incompatibilités
les API retirées, …
• Ajouter en tant que dépendances les API retirées
JavaFX, API Java EE (JAX-B, JAX-WS, JTA, CORBA, …)
• Cohabitation classpath/modulepath
l’option --illegal-access par défaut à permit
les options pour assouplir les règles de JPMS
le Multi-Release JAR
• Différentes stratégies :
migration sans module (unnamed modules)
migration qu’avec des modules (application named modules)
migration incrémentales (automatic modules)
#ParisJUG
Java 11 vers 17
39
• Plus simple que de Java 8 à 11
• Attention aux API retirées (celles forRemoval=true)
• Nashorn retiré (Java 15)
• Idéalement requiert un code coverage à 100%
à cause de l’encapsulation forte des API du JDK
#ParisJUG
Encapsulation forte des API
internes du JDK
40
• Depuis Java 9, l’option --illegal-access
contrôle l’accès par introspection par les unnamed modules
par défaut à permit pour des raisons des compatibilités
affiche un warning à chaque premier accès
• Ne pas ignorer ces warnings
• Java 16 : --illegal-access dépréciée et deny par défaut
• Java 17 : --illegal-access est ignorée (JEP 403)
• L’option --add-opens de la JVM
• Impact potentiel à l’exécution d’une application
InaccessibleObjectException, IllegalAccessError, …
#ParisJUG
Java 8 vers 17
41
• Evitez le grand saut
• Migrer avec étapes, idéalement 2 minimum
• migrer de 8 à 11
• migrer de 11 à 17
• Avec un seul déploiement en production
pour réduire les coûts (notamment de tests)
• pour ne pas avoir tous les problèmes à gérer en même temps
• assurer un meilleur suivi de l’avancement
#ParisJUG
Le futur
#ParisJUG
Les projets du futur de Java
43
• De nombreux projets sont en cours
certains partiellement livrés ou en cours de livraison
• Amber : évolutions syntaxiques (pattern matching, …)
• Panama : interactions JVM / natif
Vector API, Foreign function & Memory API, …
• Loom : threads légers
2 JEPs en preview en Java 19
• Valhalla : fonctionnalités avancées
value/primitive types, generic specialization
• Leyden : faiblesses de la JVM et convergence avec Java Native
réduire temps de démarrage, empreintes, …
Rémi
#ParisJUG
Pattern Matching pour switch
(Preview Java 17)
44
• Utilisation de patterns dans les case
guarded pattern, parenthesized pattern
• Support de null dans les case
• Doit évoluer dans les futures versions de Java
déconstruction, deconstruction pattern (array et record), …
static void afficherCercle(Forme f) {
String message = switch (f) {
case Cercle c && (c.getAire() > 100) -> "Grand cercle";
case Cercle c -> "Petit cercle";
default -> "Pas un cercle";
};
System.out.println(message);
}
#ParisJUG
Record Pattern (Preview Java 19)
45
• Pattern pour déconstruire un record
• Combinable avec un type pattern
public record Point(int x, int y) {}
public static void afficher(Object o) {
if (o instanceof Point(int x, int y)) {
System.out.println("x="+x+", y="+y);
}
}
#ParisJUG
Le futur de l’écosystème Java
46
• Java Native (Java Static) pour une compilation native
GraalVM Native Image
• Des frameworks s’appuient dessus :
Micronaut
Quarkus
Spring Native
• L’outillage évoluent aussi :
IDE, Maven 5
…
• Java 19 sera diffusée en septembre 2022
• Java 21, prochaine LTS, sera diffusée en septembre 2023
Cédric
Hervé
#ParisJUG
Conclusion
#ParisJUG
Conclusion
48
• Java poursuit son évolution
• pour offrir de nouvelles fonctionnalités
• pour simplifier le code et augmenter la productivité des devs
• La plateforme poursuit aussi sa cure d’amaigrissement
avec des fonctionnalités retirées ou bientôt retirées
• Pour en profiter, il faut migrer
• pour améliorer les performances et la sécurité
#ParisJUG
Merci pour votre attention
49
#ParisJUG

Javaday Paris 2022 - Java en 2022 : profiter de Java 17

  • 1.
    #ParisJUG 1 Java en2022 : profiter de Java 17 JMdoudouX
  • 2.
    #ParisJUG Java a évoluésur la décade 2 • Avec pas moins de 10 versions publiées grâce au nouveau modèle de releases • Avec un accueil partagé/mitigé selon les versions qui sont passés par différentes couleurs de l’arc en ciel • Trois versions LTS Java 10, 12, 13, 14, 15, 16 : transparence Java 8 : fort engouement Java 11 : adoption (très) lente Java 17 : bonheur des devs • Sept versions non-LTS Java 9 : a cassé l’engouement
  • 3.
    #ParisJUG Quelle version utilisezvous en prod ? 3 • Java 17 • Java 11 • Java 8 • Java 7 • Java < 7
  • 4.
    #ParisJUG 4 Jean-Michel Doudoux http://www.jmdoudoux.fr @jmdoudoux Co-fondateurdu , membre du Auteur de 2 didacticiels Diffusés sous licence GNU FDL • Développons en Java (4001 pages) • Développons en Java avec Eclipse CTO et
  • 5.
    #ParisJUG Roadmap 5 • Le présent •La migration vers Java 11 et 17 • Convaincre l’exploitation • Le futur • Le passé • 10 ans d’évolutions de Java • Convaincre le management • Mettre en œuvre la migration
  • 6.
  • 7.
    #ParisJUG 2012 7 • La versioncourante est Java 7 (juillet 2011) • NIO 2 Path, Files, Glob, WatchService, DirectoryStream, walkFileTree() … • Des APIs requises pour Java 8 : fork/join, invoke dynamic • Le projet Coins try with resources, exceptions multiples dans catch, opérateur diamant, String dans switch, underscore dans les littéraux numériques long valeur = 10_000_000_000L; long valeur = 1_0_0_0_0_0_0_0_0_0_0L;
  • 8.
    #ParisJUG Java 8 8 • Sortieen mars 2014 • Les expressions Lambda et les références de méthode • Une approche fonctionnelle du traitement de données avec l’API Stream • L’API Date & Time • Redonne un fort engouement pour Java • Les méthodes par défaut et static dans les interfaces • Les classes Optional • Les annotations répétées
  • 9.
    #ParisJUG Java 9 :syntaxe 9 • Evolutions mineures dans le langage @SafeVarags sur des méthodes privées l’opérateur diamant sur les classes anonymes try with resources : utilisation directe de variables explicitement final le caractère _ (underscore) est un mot clé réservé les méthodes privées dans les interfaces // Java 7 et 8 public void lire(FileInputStream fis) { try(FileInputStream fisr = fis) { // ... } // Java 9 public void lire(FileInputStream fis) { try(fis) { // ... } • Sortie en septembre 2017
  • 10.
    #ParisJUG Java 9 :API /Outils 10 • JShell : outil de type REPL tester une portion de code ou expérimenter une API • API Process interface ProcessHandle • Fabriques statiques pour collections immuables • Stackwalking API • Flow API (Reactive Streams) • VarHandle opérations atomiques/ordonnées via une référence typée à une variable List<String> lettres = List.of("a", "b", "c", "d");
  • 11.
    #ParisJUG Java 9 :les modules 11 • Les principaux objectifs proposent d’améliorer : la fiabilité de la configuration (reliable configuration) la sécurité avec l’encapsulation forte (strong encapsulation) la performance la maintenabilité • La fonctionnalité la plus impactante … et la plus controversée • La mise en œuvre implique des contraintes ruptures (visibilité, accessibilité, organisation du code, …) • Solutions pour faire cohabiter monde modulaire et non modulaire • Rendre modulaire une application n’est pas obligatoire • Création de JRE personnalisés via l’outil jlink
  • 12.
    #ParisJUG L’instruction var(Java 10) 12 •Pour faciliter la définition de variables var salutation = "Bonjour"; var bonneChancePourNommerCetteVariable = personnes.stream().collect(...))))))); var service = new Object() { void afficher() {} void calculer() {} }; service.calculer(); service.afficher(); • Le type inféré est parfois surprenant var liste = List.of("test",1); List<Serializable & Comparable<? extends Serializable & Comparable<?>>> En Java 11 List<Serializable & Comparable<? extends Serializable & Comparable<?> & java.lang.constant.Constable & java.lang.constant.ConstantDesc> & java.lang.constant.Constable & java.lang.constant.ConstantDesc> En Java 17 • Nouvelles opportunités avec les classes anonymes Map<Integer, Map<String, Map<String, Map<Integer, List<Personne>>>>> bonneChancePourNommerCetteVariable = personnes.stream.collect(...))))))); var var = personnes.stream().collect(...)))))));
  • 13.
    #ParisJUG Support des conteneurs 13 •Bien meilleur support en Java 10 • Détection de l’exécution dans un conteneur Docker • Backport en Java 8u191 • Prise en compte des limitations de ressources (cgroups) • Options plus fines pour la gestion de la mémoire Brice et J-Philippe
  • 14.
    #ParisJUG Java 11 14 • Diffuséeen septembre 2018 • Version importante car LTS • Exécution directe d’un unique fichier .java par la JVM sans compilation préalable • API HTTP Client support HTTP 1.1 et 2, websockets, synchrone/asynchrone • JDK Flight Recorder
  • 15.
    #ParisJUG Switch expressions(Java 14) 15 switch(niveau) { case 1, 2 -> { System.out.print("Débutant"); System.out.println(" et junior"); } case 3, 4 -> System.out.println("Confirmé"); case 5 -> System.out.println("Expert"); } String libelle = switch (niveau) { case 1, 2 -> "Débutant"; case 3, 4 -> "Confirmé"; case 5 -> "Expert"; default -> { System.out.println("cas par défaut"); yield "Non défini"; } }; System.out.println(libelle); String libelle = switch (niveau) { case 1, 2 : yield "Débutant"; case 3, 4 : yield "Confirmé"; case 5 : yield "Expert"; default : { System.out.println("cas par défaut"); yield "Non défini"; } }; System.out.println(libelle); switch (niveau) { case 1, 2 : System.out.print("Débutant"); System.out.println(" et junior"); break; case 3, 4 : System.out.println("Confirmé"); break; case 5 : System.out.println("Expert"); break; }
  • 16.
    #ParisJUG Blocs de texte(Java15) 16 • Exprimer une chaîne de caractères littérale multiligne simplement : basiquement sans séquence d’échappement • Gestion de l’indentation accessoire/significative en début et fin en déplaçant le contenu vers la droite en déplaçant le délimiteur de fermeture vers la gauche • 2 nouveaux caractères d’échappement s pour indiquer un espace <retour_chariot> supprime la fin de ligne String html = """ <HTML> <BODY> <H1>"Hello"</H1> </BODY> </HTML>"""; String html = """ <HTML> <BODY> <H1>"Hello"</H1> </BODY> </HTML>"""; String html = """ <HTML> <BODY> <H1>"Hello"</H1> </BODY> </HTML> """;
  • 17.
    #ParisJUG Helpful NullPointerException (Java15) 17 • On rencontre fréquemment des exceptions de type NPE • Hormis la stacktrace, pas d’informations utiles • JVM réalise une analyse du byte-code pour fournir un message d’erreur utile sur une NPE (conséquence, cause) d’autant plus précis avec info de débogage (-g du compilateur) • Le message fourni est contextuel C:java>javac -g TestNPE.java C:java>java TestNPE Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "message" is null at TestNPE.main(TestNPE.java:5)
  • 18.
    #ParisJUG Pattern matching pourinstanceof (Java 16) 18 • Pour simplifier le code • Utilisation de l’opérateur && if (obj instanceof Groupe) { Groupe groupe = (Groupe) obj; var membres = groupe.membres(); } if (obj instanceof Groupe groupe) { var membres = groupe.membres(); } if (obj instanceof Groupe groupe && !groupe.membres().isEmpty()) { System.out.println(groupe.membres()); }
  • 19.
    #ParisJUG Les records(Java 16) 19 •Un nouveau type pour définir une classe • Encapsulant des données de manière immuable • Avec une syntaxe concise utilisant l’identifiant restreint record • Un record peut être personnalisé avec un constructeur compact public record Formation(String titre, String code, Duration duree) { } public record Formation(String titre, String code, Duration duree) { public Formation { if (titre.isBlank()) { throw new IllegalArgumentException("Le titre doit être renseigné"); } } }
  • 20.
    #ParisJUG Les records(Java 16) 20 •Possibilité de définir et utiliser des records locaux implicitement static • Mais aussi des interfaces et énumérations locales (Java 15) • Les records sont immuables au sens Java • Les records sont « vraiment » immuables il n’est pas possible de modifier la valeur/référence d’un composant même en utilisant l’API Reflection ou VarHandle • La désérialisation d’un record est différente elle invoque le constructeur canonique
  • 21.
    #ParisJUG Les classes scellées(Java 17) 21 • Fonctionnalité standard pour restreindre par déclaration les classes qui peuvent étendre une classe scellée les classes qui peuvent implémenter une interface scellée • But : connaître de manière exhaustive les sous-types • 3 nouveaux mots-clés contextuels : sealed, non-sealed et permits • Les classes filles doivent avoir un des modificateurs final, sealed ou non-sealed • 2 contraintes sur l’endroit où pourront être les classes filles dans un module nommé : dans le même module que leur classe mère dans un unnamed module : dans le même package que leur classe mère public sealed class Forme permits Cercle, Triangle {}
  • 22.
    #ParisJUG Java 17 22 • Diffuséeen septembre 2021 • Nouvelle version majeure car LTS • Le Security Manager est déprécié forRemoval • Oracle diffuse son JDK sous licence NFTC No-Fee Terms and Conditions • Réduction de la durée entre 2 LTS à 2 ans
  • 23.
    #ParisJUG Java 18 23 • Diffuséeen mars 2022 • UTF-8 par défaut (sauf sortie console) • Le mécanisme finalize est déprécié • Les extraits de code dans la Javadoc avec @snippet • Un serveur web minimaliste • Des améliorations dans les ramasse-miettes et la sécurité
  • 24.
    #ParisJUG Bilan de sesévolutions 24 • Souvent la verbosité est reprochée à Java • Java se modernise et se simplifie • Les évolutions présentées ne sont que les principales • Il y en a beaucoup d’autres : Collector teeing (Java 12) jpackage (java 16) hidden class (Java 15) default et dynamic CDS archive (Java 12 et 13) Stream::toList() (Java 16) java.text.CompactNumberFormat (Java 12) …
  • 25.
  • 26.
    #ParisJUG Le plus durreste à faire 26 • Maintenant que vous être convaincus • Le plus dur reste à faire • Convaincre l’exploitation • Pour migrer vers une LTS plus récente : Java 11 ou 17 • Et donc budgéter et planifier cette migration … et le management
  • 27.
  • 28.
    #ParisJUG Utiliser les évolutionsvues 28 • Pour nous dev, beaucoup de choses sympa • dans la syntaxe • dans les API • Mais malheureusement peu recevables d’un point de vue exploitation • Surtout que pour de (bonnes) raisons, elle est conservatrice
  • 29.
    #ParisJUG Les arguments recevables 29 •Les devs focalisent beaucoup sur la syntaxe et les API • Mais l’élément majeur de Java c’est la JVM • La JVM évolue aussi notamment sur • La performance • Et la sécurité • Deux préoccupations majeures de l’exploitation
  • 30.
    #ParisJUG Performance 30 • La JVMde chaque version LTS améliore les performances de manière globale dépend du type d’application et de son activité • Les ramasse-miettes évoluent tous, G1 par défaut sur JVM server (Java 9) • Et de nouveaux sont ajoutés : ZGC, Shenandoah, Epsilon GC • Le JIT • Des optimisations dans les implémentations des API compact String (Java 9), … • Ça fonctionne bien en Java 8 -> encore mieux en 11 ou 17
  • 31.
    #ParisJUG Sécurité 31 • Maj RootCA Certificates et algo faibles désactivés • Support de TLS 1.3 (Java 11) • Algo de cryptographie : ChaCha20 et ChaCha20-Poly1305 (Java 11) Edwards-Curve Digital Signature Algorithm (EdDSA) (Java 15) • PKCS12 par défaut dans le keystore (Java 9) • SHA-3 (Java 9) • Support de TLS 1.0 et 1.1 retirés (Java 16) • Filter Incoming Serialization Data (Java 9) Context-Specific Deserialization Filters (Java 17) Charles
  • 32.
  • 33.
    #ParisJUG Les coûts 33 • Trèsvariables pour la migration selon l’état de l’application surtout avec les tests • De la version courante (8 / 11) et ciblée de Java (11 / 17) • Les performances peuvent réduire les coûts d’exploitation surtout dans le cloud GCs qui restituent la mémoire inutilisée au système compact Strings (économie de heap) jlink pour des runtimes personnalisés ….
  • 34.
    #ParisJUG D’autres arguments 34 • Trèsdifficile de recruter actuellement • Encore plus sur des technologies obsolètes • Migrer pour être sur un socle plus récent, peut faciliter • Mais aussi pour limiter le turn over • Car au final le coût est parfois supérieur à celui de la migration • Et puis … la RGPD pour un aspect légal
  • 35.
  • 36.
    #ParisJUG Règles générales demigration > 8 36 • Mettre à jour les outils avec une version compatible avec la version de Java ciblée • Mettre à jour les dépendances avec une version compatible avec la version de Java ciblée • Utiliser jdeps (sur app et toutes les dépendances) pour une cartographie des dépendances les API internes utilisées détecter les splits packages • Mythe urbain : aucune obligation de modulariser l’application migrer en laissant tout dans le classpath modulariser si possible
  • 37.
    #ParisJUG Des API retirées 37 •A partir de Java 11, toutes les versions de Java retirent des API • Celles marquées dans la ou les versions précédentes avec • Consultez les listes de différences entres versions de Java https://javaalmanac.io/ https://foojay.io/almanac/java-17/ • Utilisez jdeprscan pour obtenir les API dépréciées du JDK à utiliser sur tout le classpath et modulepath @Deprecated(forRemoval=true)
  • 38.
    #ParisJUG Java 8 vers11 38 • Régler les incompatibilités les API retirées, … • Ajouter en tant que dépendances les API retirées JavaFX, API Java EE (JAX-B, JAX-WS, JTA, CORBA, …) • Cohabitation classpath/modulepath l’option --illegal-access par défaut à permit les options pour assouplir les règles de JPMS le Multi-Release JAR • Différentes stratégies : migration sans module (unnamed modules) migration qu’avec des modules (application named modules) migration incrémentales (automatic modules)
  • 39.
    #ParisJUG Java 11 vers17 39 • Plus simple que de Java 8 à 11 • Attention aux API retirées (celles forRemoval=true) • Nashorn retiré (Java 15) • Idéalement requiert un code coverage à 100% à cause de l’encapsulation forte des API du JDK
  • 40.
    #ParisJUG Encapsulation forte desAPI internes du JDK 40 • Depuis Java 9, l’option --illegal-access contrôle l’accès par introspection par les unnamed modules par défaut à permit pour des raisons des compatibilités affiche un warning à chaque premier accès • Ne pas ignorer ces warnings • Java 16 : --illegal-access dépréciée et deny par défaut • Java 17 : --illegal-access est ignorée (JEP 403) • L’option --add-opens de la JVM • Impact potentiel à l’exécution d’une application InaccessibleObjectException, IllegalAccessError, …
  • 41.
    #ParisJUG Java 8 vers17 41 • Evitez le grand saut • Migrer avec étapes, idéalement 2 minimum • migrer de 8 à 11 • migrer de 11 à 17 • Avec un seul déploiement en production pour réduire les coûts (notamment de tests) • pour ne pas avoir tous les problèmes à gérer en même temps • assurer un meilleur suivi de l’avancement
  • 42.
  • 43.
    #ParisJUG Les projets dufutur de Java 43 • De nombreux projets sont en cours certains partiellement livrés ou en cours de livraison • Amber : évolutions syntaxiques (pattern matching, …) • Panama : interactions JVM / natif Vector API, Foreign function & Memory API, … • Loom : threads légers 2 JEPs en preview en Java 19 • Valhalla : fonctionnalités avancées value/primitive types, generic specialization • Leyden : faiblesses de la JVM et convergence avec Java Native réduire temps de démarrage, empreintes, … Rémi
  • 44.
    #ParisJUG Pattern Matching pourswitch (Preview Java 17) 44 • Utilisation de patterns dans les case guarded pattern, parenthesized pattern • Support de null dans les case • Doit évoluer dans les futures versions de Java déconstruction, deconstruction pattern (array et record), … static void afficherCercle(Forme f) { String message = switch (f) { case Cercle c && (c.getAire() > 100) -> "Grand cercle"; case Cercle c -> "Petit cercle"; default -> "Pas un cercle"; }; System.out.println(message); }
  • 45.
    #ParisJUG Record Pattern (PreviewJava 19) 45 • Pattern pour déconstruire un record • Combinable avec un type pattern public record Point(int x, int y) {} public static void afficher(Object o) { if (o instanceof Point(int x, int y)) { System.out.println("x="+x+", y="+y); } }
  • 46.
    #ParisJUG Le futur del’écosystème Java 46 • Java Native (Java Static) pour une compilation native GraalVM Native Image • Des frameworks s’appuient dessus : Micronaut Quarkus Spring Native • L’outillage évoluent aussi : IDE, Maven 5 … • Java 19 sera diffusée en septembre 2022 • Java 21, prochaine LTS, sera diffusée en septembre 2023 Cédric Hervé
  • 47.
  • 48.
    #ParisJUG Conclusion 48 • Java poursuitson évolution • pour offrir de nouvelles fonctionnalités • pour simplifier le code et augmenter la productivité des devs • La plateforme poursuit aussi sa cure d’amaigrissement avec des fonctionnalités retirées ou bientôt retirées • Pour en profiter, il faut migrer • pour améliorer les performances et la sécurité
  • 49.
  • 50.