← Java SE 21 — préparation OCP

Module 5 / 8 · 90 min

Exceptions, fichiers et sérialisation

Attribuer la propriété des ressources et fermer les flux.

Votre progression apparaîtra ici lorsque JavaScript est actif.

La progression et le meilleur score sont enregistrés uniquement dans ce navigateur. Aucun compte n’est nécessaire ; effacer les données du navigateur les supprime. Les durées de modules sont indicatives et incluent les exercices.

Comprendre le mécanisme

Les exceptions checked doivent être capturées ou déclarées selon le contrat d’appel. try-with-resources ferme les ressources AutoCloseable dans l’ordre inverse de leur déclaration. Si le corps échoue et que close échoue aussi, l’exception de fermeture peut être supprimée au profit de l’exception principale. Enfin, Path.normalize simplifie la représentation lexicale ; il ne vérifie pas les liens symboliques ni l’existence de la cible.

Raisonner et vérifier

Un Stream<String> renvoyé par Files.lines possède une ressource à fermer. Évitez de charger un fichier arbitrairement grand sans limite. Pour la sérialisation Java native, définissez une frontière de confiance et des filtres adaptés : un format d’objet n’est pas un schéma métier validé. Un chemin provenant du client doit être contraint au répertoire autorisé avec une stratégie compatible avec les liens et la concurrence.

Signaler une exception selon sa catégorie

Java distingue des catégories d’exceptions dont les règles de capture ou de déclaration diffèrent. Une exception vérifiée peut obliger le consommateur à traiter explicitement un échec possible. Cette obligation de compilation ne décide pas du résultat métier après une écriture. Choisissez la frontière capable d’annuler, traduire ou reprendre, et vérifiez les effets déjà réalisés avant l’exception. Un simple catch vide ne rend pas le parcours correct.

Erreur fréquente à comprendre

Toute exception Java est non vérifiée.

La hiérarchie distingue plusieurs catégories.

Fermer les ressources du parcours

try-with-resources organise la fermeture des ressources compatibles avec son contrat. Le Stream obtenu par Files.lines est lié à une ressource de lecture et doit être fermé, par exemple dans ce bloc. La présence d’opérations de stream ne retire pas le besoin de gérer le fichier. Testez le traitement complet et une interruption précoce du parcours afin de vérifier le nettoyage prévu.

Erreur fréquente à comprendre

Une ressource AutoCloseable reste toujours ouverte après ce bloc.

Le mécanisme organise sa fermeture.

L’ordre inverse correspond aux dépendances

Plusieurs ressources déclarées dans un même bloc sont fermées dans l’ordre inverse de leur déclaration. Cette règle convient notamment lorsque les ressources créées plus tard dépendent des précédentes. Tracez acquisition, travail puis fermeture comme trois phases séparées. Pour expliquer une sortie console, notez d’abord ce qui est affiché dans le corps avant d’ajouter les événements de nettoyage ; ils ne se produisent pas tous à la construction.

Erreur fréquente à comprendre

L’ordre de fermeture est toujours celui de déclaration.

Le nettoyage suit l’ordre inverse de construction dans ce contrat.

Préserver la cause initiale

Une erreur pendant le travail peut être accompagnée d’une autre erreur pendant close. Le mécanisme de ressources peut conserver une exception comme supprimée plutôt que remplacer systématiquement la cause principale. Une investigation doit donc examiner les informations pertinentes de l’exception, pas seulement son message public. Les logs restent privés et minimisés ; présenter toute la pile à l’utilisateur n’est pas nécessaire pour signaler un échec contrôlé.

Erreur fréquente à comprendre

Toute erreur de fermeture remplace nécessairement l’erreur initiale.

Le mécanisme conserve aussi des exceptions supprimées.

Un chemin reçu n’est pas une permission

Un client peut fournir un nom ou identifiant de document sans posséder le droit de lire le fichier résolu. Préférez un identifiant métier relié côté serveur à une ressource maîtrisée. Vérifiez l’autorisation avant ouverture et évitez les concaténations qui donnent au client tout l’espace de fichiers. Le test doit demander un document tiers et un chemin hors périmètre, puis observer un refus sans lecture interdite.

Erreur fréquente à comprendre

Un chemin absolu client donne une permission de lecture.

Le système doit limiter les ressources accessibles.

Normalisation lexicale et résolution réelle

Path.normalize simplifie une représentation de chemin, par exemple des segments relatifs. Il ne prouve pas à lui seul que le fichier effectivement ouvert reste dans une racine, notamment avec des liens symboliques et des changements concurrents. Définissez le modèle de résolution et les garanties du stockage. Un test purement textuel ne couvre pas les conditions réelles du système de fichiers ni toutes les courses entre contrôle et utilisation.

Erreur fréquente à comprendre

normalize seul prouve tout confinement sur le système réel.

La résolution effective peut introduire d’autres frontières.

Définir l’encodage du document

Des octets ne constituent pas automatiquement un texte conforme au format attendu. Choisissez le charset et la politique face à une séquence invalide avant de traiter une importation. Un résultat lisible sur une machine ne garantit pas une lecture identique dans un autre environnement configuré différemment. Les fixtures doivent contenir texte international, caractères limites et données invalides pour vérifier la propriété annoncée.

Erreur fréquente à comprendre

Toute suite d’octets est un texte UTF-8 valide.

La validité d’encodage demande un contrat.

Borner le volume consommé

Une lecture complète en mémoire comme readAllBytes possède un coût lié au fichier. Un droit d’accès correct n’autorise pas une consommation illimitée. Définissez taille maximale, stratégie de lecture et comportement lorsque la limite est atteinte. Un flux progressif peut aider, mais seulement si le consommateur n’accumule pas ensuite tout le contenu. Mesurez la mémoire et le temps sur un fichier proche de la borne choisie.

Erreur fréquente à comprendre

readAllBytes est sans coût mémoire quelle que soit la taille.

La méthode charge les octets en mémoire.

Nettoyage et succès sont distincts

Fermer une ressource correctement ne valide pas une transaction métier. Une opération peut avoir échoué puis libéré ses fichiers comme prévu. Le résultat public et le code de sortie doivent conserver cette distinction, faute de quoi une CI ou un service appelant peut interpréter le nettoyage comme un succès. Testez simultanément le diagnostic attendu et l’état final des ressources et données.

Erreur fréquente à comprendre

Une fermeture réussie valide automatiquement la transaction.

Libération et réussite sont des propriétés différentes.

Donner un diagnostic sans dévoiler les chemins

Une erreur de fichier peut contenir une arborescence interne, un nom de compte ou d’autres informations sensibles. La réponse publique doit fournir un code utile et une corrélation maîtrisée. Le diagnostic privé peut conserver davantage de contexte selon les droits et la conservation prévus. Les tests d’erreur doivent examiner le corps retourné : le parcours exceptionnel ne doit pas devenir un canal de divulgation absent du parcours nominal.

Erreur fréquente à comprendre

Une API doit afficher chaque chemin interne sur échec.

Le diagnostic détaillé doit rester contrôlé.

Atelier guidé : lire, expliquer et vérifier le code

class Resource implements AutoCloseable {
    private final String name;
    Resource(String name) { this.name = name; }
    public void close() { System.out.print(name); }
}
class Main {
    public static void main(String[] args) {
        try (var a = new Resource("A"); var b = new Resource("B")) {
            System.out.print("X");
        }
    }
}

Le corps du bloc affiche d’abord X. Les ressources ont été déclarées dans l’ordre A puis B ; la fermeture commence par B et se termine par A. La sortie est donc XBA. close ne se déclenche pas avant le travail du bloc et les ressources sont bien compatibles avec le mécanisme utilisé.

Ajoutez dans une copie de laboratoire une exception pendant le corps, puis une autre pendant une fermeture. Examinez la cause principale et les exceptions supprimées avec un test local expurgé. Remplacez enfin la ressource artificielle par une lecture de fichier contrôlée. La finalité reste de vérifier le cycle d’acquisition et de libération, sans confondre ce nettoyage avec la réussite de l’opération métier utilisant les données lues.

Spring : exception checked et règle de rollback

La présence d’une exception ne signifie pas que toute transaction Spring est automatiquement annulée. Dans le comportement standard du scénario, RuntimeException et Error déclenchent le rollback, tandis qu’une IOException checked qui s’échappe ne l’impose pas à elle seule.

Si les écritures ont réussi et qu’aucune autre cause n’a marqué la transaction rollback-only, elles peuvent donc être commitées malgré cette exception. Configurez rollbackFor pour la classe pertinente lorsque le contrat métier exige l’annulation, ou adoptez une politique globale explicite et revue. Les versions et options qui modifient les défauts doivent être prises en compte ; l’exercice les exclut précisément.

Testez depuis un appel externe qui traverse le proxy et inspectez le stockage après la fin de la transaction. Un test enveloppé dans sa propre transaction automatiquement annulée peut masquer le commit réel que vous cherchez à observer. Couvrez exception checked, runtime et chemin nominal avec les règles effectivement configurées.

Points de vigilance : Le comportement standard ne marque pas automatiquement le rollback pour toutes les exceptions checked. Une transaction locale n’annule pas arbitrairement sa dernière instruction. Sans autre cause de rollback, cette exception ne déclenche pas la règle standard ; rollbackFor peut l’inclure. Le type Java de l’exception n’est pas converti automatiquement ainsi.

Documentation de référence ↗

Exemple commenté

try (var lines = java.nio.file.Files.lines(java.nio.file.Path.of("reservations.csv"))) {
    System.out.println(lines.filter(line -> !line.isBlank()).count());
}

Le flux est fermé après le bloc, y compris si le comptage échoue. L’exemple suppose un fichier de laboratoire déjà présent.

Exercice de mise en pratique

Lisez un CSV ligne par ligne, conservez le numéro des lignes invalides et garantissez la fermeture du flux.

Voir une proposition de correction

Entourez Files.lines d’un try-with-resources ; séparez parsing et validation. Testez fichier absent, ligne mal formée et erreur pendant la lecture.

Points de vérification

  • Fermer les ressources possédées.
  • Distinguer normalisation et résolution réelle.
  • Conserver l’exception principale.

Contrôle de connaissances

Cours associé : Exceptions, fichiers et sérialisation ↗
Faut-il fermer le Stream retourné par Files.lines ?

Documentation de référence ↗

Validation du module

101 questions, objectif pédagogique de 75 %. Durée conseillée de 150 minutes, sans limite imposée. Les questions et les choix sont mélangés ; le corrigé apparaît après validation. Le contrôle rapide de la leçon et l’examen final du cours restent des exercices distincts.

Commencer ou reprendre les 101 questions →