Jetez un œil aux erreurs d'exécution Java

Feb 26 2023
Un aperçu rapide des erreurs d'exécution Java · Que sont les erreurs d'exécution en Java ? · Erreur d'exécution VS erreur de compilation · Types d'erreurs d'exécution · Comment l'erreur d'exécution apparaît-elle ? · Dois-je lancer des erreurs d'exécution · Que s'est-il passé lorsque vous ne t attraper une exception d'exécution · Exemple d'erreur d'exécution Que sont les erreurs d'exécution en Java ? Les erreurs qui se produisent au moment de l'exécution du programme sont appelées erreurs d'exécution. Ces types d'erreurs ne peuvent pas être détectés au moment de la compilation car il n'y a rien de mal avec leur syntaxe.

Un aperçu rapide des erreurs d'exécution Java

· Que sont les erreurs d'exécution en Java ?
· Erreur d'exécution contre erreur de compilation
· Types d'erreurs d'exécution
· Comment l'erreur d'exécution apparaît-elle ?
· Dois-je lancer des erreurs d'exécution
· Que se passe-t-il lorsque vous n'attrapez pas d'exceptions d'exécution
· Exemple d'erreur d'exécution

Que sont les erreurs d'exécution en Java ?

Les erreurs qui se produisent au moment de l'exécution du programme sont appelées erreurs d'exécution. Ces types d'erreurs ne peuvent pas être détectés au moment de la compilation car il n'y a rien de mal avec leur syntaxe. Ainsi, les erreurs d'exécution se produisent lorsque le programme a été compilé avec succès sans générer d'erreur et en créant un fichier ".class". Cependant, le programme ne s'exécute pas correctement. Ces erreurs sont détectées à l'exécution ou au moment de l'exécution du programme.

Le compilateur Java ne détecte pas les erreurs d'exécution car le compilateur Java ne dispose d'aucune technique pour détecter ces erreurs car il ne dispose pas de toutes les informations d'exécution disponibles. Les erreurs d'exécution sont capturées par Java Virtual Machine (JVM) lorsque le programme est en cours d'exécution.

Ces erreurs d'exécution sont appelées exceptions et elles terminent le programme de manière anormale, en donnant une instruction d'erreur.

Les exceptions sont des erreurs générées lors de l'exécution. Nous pouvons utiliser des techniques de gestion des exceptions en Java pour gérer ces erreurs d'exécution. Dans la gestion des exceptions, le morceau de code que le programmeur pense pouvoir produire l'erreur est placé dans le bloc try et le programmeur peut intercepter l'erreur dans le bloc catch.

Erreur d'exécution VS erreur de compilation

Une erreur de compilation fait généralement référence aux erreurs qui correspondent à la sémantique ou à la syntaxe. Une erreur d'exécution fait référence à l'erreur que nous rencontrons lors de l'exécution du code lors de l'exécution . Nous pouvons facilement corriger une erreur de compilation lors du développement du code. Un compilateur ne peut pas identifier une erreur d'exécution.

Détection

Les compilateurs peuvent facilement détecter les erreurs de compilation pendant le développement du code. Un compilateur ne peut pas facilement détecter une erreur d'exécution. Ainsi, nous devons l'identifier lors de l'exécution du code.

Référence

Une erreur de compilation fait généralement référence aux erreurs qui correspondent à la sémantique ou à la syntaxe.

impact

Les erreurs de compilation sont des erreurs de sémantique ou de syntaxe , elles empêchent le code de s'exécuter (compiler) car il détecte certaines erreurs de syntaxe. Les erreurs d'exécution Wheares empêchent l'exécution complète du code.

Fixation

Nous pouvons facilement corriger une erreur de compilation lors du développement du code. Un compilateur ne peut pas identifier une erreur d'exécution. Mais nous pouvons le réparer après l'exécution du code et l'identification du code au préalable.

Types d'erreurs d'exécution

Il existe plusieurs types d'erreurs d'exécution auxquelles nous pouvons être confrontés au moment de l'exécution du programme. Certaines erreurs d'exécution fréquemment rencontrées sont répertoriées ci-dessous :

Erreurs de saisie : Erreurs d'entrée-sortie

Il existe d'innombrables façons dont l'entrée de l'utilisateur peut corrompre une application.

Sur un tableau de commentaires basé sur HTML, un utilisateur autorisé à soumettre innocemment un signe non codé inférieur à (<) ou supérieur à (>) a le potentiel de ruiner complètement la capacité de rendu de cette page Web. De même, les systèmes de traitement de texte conçus pour attendre toutes les entrées au format ASCII peuvent se terminer prématurément s'ils reçoivent des emojis ou des entrées de caractères non standard.

Plus néfaste encore, l'un des vecteurs d'attaque préférés des pirates est l'injection SQL , qui cache une requête de base de données exécutable nuisible dans un champ de saisie autrement inoffensif. Cela peut non seulement entraîner l'échec d'une application, mais également abandonner le contrôle de l'ensemble de la couche de données.

Le processus de nettoyage des entrées, ou nettoyage des données , convertit le large éventail de données susceptibles d'être entrées dans les applications en une plage de valeurs sûre qu'un programme comprend. L'utilisation de ces bibliothèques permet d'atténuer les erreurs d'exécution causées par les échecs de nettoyage des entrées.

Les frameworks Java populaires tels qu'Apache BVal et Hibernate Validator effectuent un nettoyage simple des entrées basé sur des annotations et s'intègrent facilement dans n'importe quelle application basée sur Java.

Logique mal implémentée

Ce n'est pas parce que le code compile qu'il fonctionne correctement. Le code contient souvent des problèmes logiques qui provoquent l'échec d'une application lors de l'exécution.

Java contient une construction intégrée pour gérer une classe d'erreurs d'exécution courantes liées au code, appelée RuntimeException, ou l'exception non vérifiée. Java 17 définit 78 erreurs de ce type dans le SDK seul, et d'autres projets et frameworks définissent en outre leurs propres erreurs RuntimeException.

  • Exception d'exécution
  • ArrayIndexOutOfBoundException
  • ConcurrentModificationExceptionConcurrentModificationException
  • ClassCastException
  • …

À tout le moins, chaque application devrait inclure un harnais d'exception générique qui peut intercepter toutes les RuntimeException possibles, enregistrer l'erreur et permettre au thread d'exécution problématique de mourir plutôt que d'abandonner l'ensemble de l'application.

Ressources d'exécution insuffisantes

Les développeurs de logiciels ne sont pas responsables de chaque type d'erreur d'exécution qui se produit. De nombreuses erreurs d'exécution dans Java impliquent des limitations de ressources causées par des problèmes avec l'infrastructure sous-jacente. Les exemples incluent : les délais d'expiration du réseau, les conditions de mémoire insuffisante , la surutilisation du processeur ou l'incapacité de planifier un thread sur le processeur.

Une façon d'éviter les erreurs d'exécution liées aux ressources consiste à utiliser un outil de test de charge, tel que JMeter ou LoadRunner, dans le pipeline CI/CD d'une application. Si ces outils détectent un éventuel problème de performances, ils peuvent arrêter l'application avant qu'elle ne progresse dans le pipeline vers le déploiement en production.

La charge de certaines applications varie considérablement. Par exemple, une application de services financiers peut afficher une charge constante la plupart du temps, mais être extrêmement occupée à la fin de la journée de négociation. Un service fiscal peut atteindre un pic de charge avant la date limite de dépôt mais avoir relativement peu de charge le reste de l'année.

Les équipes DevOps doivent surveiller leurs mesures de performance avec des outils pour détecter et atténuer de manière préventive les erreurs d'exécution liées aux ressources. Des exemples de tels outils incluent JDK Flight Recorder et Java Mission Control .

Pour les applications avec des charges de travail totalement imprévisibles, utilisez la technologie d'équilibrage de charge basée sur le cloud pour allouer les ressources de manière élastique. Cela élimine à la fois les ressources sous-allouées et le piège de l'achat de matériel coûteux et rarement utilisé.

Configuration des ressources externes

Les applications d'entreprise existent rarement dans une bulle isolée. Ils interagissent généralement avec tout, des bases de données NoSQL et des systèmes relationnels aux files d'attente Kafka et aux API RESTful. Malheureusement, si votre application ne parvient pas à se connecter à un système externe requis, cela entraîne inévitablement une erreur d'exécution.

Une ressource externe peut précipiter une erreur d'exécution si l'une des situations suivantes se produit sans mise à jour correspondante du programme appelant :

  • une adresse IP change ;
  • modification des informations d'identification ;
  • modification de la configuration du pare-feu ; ou
  • le système externe tombe en panne pour maintenance.

Dans le même ordre d'idées, les outils d'ingénierie du chaos terminent de manière aléatoire les processus dont dépend une application. De tels outils obligent les développeurs à écrire du code qui reste réactif et résilient même en cas de défaillance des systèmes externes.

Le problème inhérent aux ressources externes est que les développeurs ne peuvent pas les contrôler, mais ils peuvent contrôler la façon dont une application répond lorsque ces ressources externes échouent. Anticipez les erreurs d'exécution générées par les systèmes que vous ne contrôlez pas et écrivez des applications qui répondent correctement lorsque ces systèmes externes échouent.

Vulnérabilités des bibliothèques tierces

Toute application d'entreprise non triviale comprend des dizaines de dépendances sur des bibliothèques tierces pour exécuter des fonctions telles que la journalisation, la surveillance, la validation des entrées, la gestion des formulaires, etc.

Malheureusement, tout bogue dans une bibliothèque tierce devient un bogue dans l'application que vous déployez. Cela est devenu inconfortablement réel pour le monde Java en décembre 2021, car une faille d'injection LDAP dans la bibliothèque Log4j 2 largement utilisée a forcé les JVM du monde entier à se déconnecter.

Une façon d'atténuer la possibilité que les dépendances logicielles introduisent des erreurs d'exécution dans les applications consiste à n'utiliser que des bibliothèques approuvées d'organisations telles qu'Apache ou Eclipse.

Une autre mesure de protection consiste à mettre régulièrement à jour les dépendances d'une application vers la dernière version dès que des mises à jour sont disponibles.

Enfin, soyez conscient des dépendances secondaires ou tertiaires - celles sur lesquelles vos dépendances primaires elles-mêmes reposent - et soyez conscient des risques que celles-ci entraînent.

Dans le monde du développement logiciel, "parfait" est l'ennemi du "fait". Aucun programme n'est à l'abri de la menace d'une erreur d'exécution imprévue. Cependant, lorsque les développeurs d'entreprise prennent conscience des causes possibles et prennent des mesures pour atténuer les menaces potentielles, ils peuvent créer un logiciel qui minimise la probabilité de rencontrer une erreur d'exécution.

Comment l'erreur d'exécution apparaît-elle ?

Toutes nos félicitations! Si votre invite de commande ressemble à ceci :

Ensuite, vous avez compilé avec succès votre programme en bytecode Java, ce qui signifie qu'il n'y a eu aucun problème de syntaxe avec votre code ! Mais, comme le nom du fichier l'indique, lorsque nous exécutons ce programme :

Nous avons maintenant rencontré une erreur d'exécution. Les erreurs d'exécution se produisent généralement lorsqu'il y a quelque chose de logiquement incorrect dans votre code. Ce document explique comment lire et corriger les erreurs d'exécution.

Voici les principales parties de l'erreur d'exécution

Exception dans le thread "main" : Cette partie apparaît pour la plupart des erreurs d'exécution. Il vous indique simplement que l'exception s'est produite dans la méthode principale, ce qui devrait se produire tout le temps.

java.lang.ArrayIndexOutOfBoundsException: 5 : Il s'agit de l'erreur qui s'est produite. Le nom de l'erreur vous donnera généralement une idée de ce qui aurait pu se passer. Dans ce cas, nous savons qu'il s'agit de tableaux et de sortir de l'espace alloué pour un tableau.

at RunTimeErrors.main(RunTimeErrors.java:10) : C'est ce qu'on appelle la trace de la pile, qui vous indique la liste des méthodes en cours d'exécution lorsque l'erreur s'est produite.

  • RunTimeErrors.main nous indique que cette erreur s'est produite dans la méthode principale de la classe RunTimeErrors.
  • RunTimeErrors.java:10 nous indique dans quel fichier cela s'est produit et à quelle ligne cela s'est produit. Dans ce cas, cela s'est produit dans notre classe principale à la ligne 10 .

Parfois, vous devez effectuer une vérification pour décider de lancer une exception d'exécution si le système ne peut pas le faire seul, souvent lorsque vous travaillez avec IllegalArgumentException, mais la plupart du temps, vous n'avez pas besoin d'effectuer une vérification car cela fait partie de la vérification d'exécution standard que Java effectue pour vous.

prenons NullPointerException comme exemple :

if(t == null) 
 throw new NullPointerException();

if(t != null) {
  // work with t reference
}

Que se passe-t-il lorsque vous n'interceptez pas les exceptions d'exécution ? Étant donné que le compilateur n'applique pas les spécifications d'exception pour celles-ci, il est tout à fait plausible qu'une RuntimeException puisse s'infiltrer jusqu'à votre méthode main() sans être interceptée. Pour voir ce qui se passe dans ce cas, essayez l'exemple suivant :

//: exceptions/NeverCaught.java 
// Ignoring RuntimeExceptions. 
// {ThrowsException} 
public class NeverCaught { 
 static void f() { 
 throw new RuntimeException("From f()"); 
 } 
 static void g() { 
 f(); 
 } 
 public static void main(String[] args) { 
 g(); 
 } 
} ///:~

Exception in thread "main" Java.lang.RuntimeException: From f() 
    at NeverCaught.f(NeverCaught.Java:7) 
    at NeverCaught.g(NeverCaught.Java:10) 
    at NeverCaught.main(NeverCaught.Java:13)

Gardez à l'esprit que seules les exceptions de type RuntimeException (et les sous-classes) peuvent être ignorées dans votre codage, car le compilateur applique soigneusement la gestion de toutes les exceptions vérifiées. Le raisonnement est qu'une RuntimeException représente une erreur de programmation, qui est :

Une erreur que vous ne pouvez pas anticiper. Par exemple, une référence null hors de votre contrôle.

Une erreur que vous, en tant que programmeur, auriez dû vérifier dans votre code (comme ArraylndexOutOfBoundsException où vous auriez dû faire attention à la taille du tableau). Une exception qui se produit à partir du point 1 devient souvent un problème pour le point

Vous pouvez voir à quel point il est avantageux d'avoir des exceptions dans ce cas, car elles facilitent le processus de débogage.

Il est intéressant de noter que vous ne pouvez pas classer la gestion des exceptions Java comme un outil à usage unique. Oui, il est conçu pour gérer ces erreurs d'exécution embêtantes qui se produiront en raison de forces indépendantes de la volonté de votre code, mais il est également essentiel pour certains types de bogues de programmation que le compilateur ne peut pas détecter.

Exemple d'erreur d'exécution

public class Temp {
public static void main(String[] args) {
  Temp t = initT();
  
  t.foo("Hi");
  
 }
 private static Temp initT() {
  return null;
 }
 public void foo(String s) {
  System.out.println(s.toLowerCase());
 }
}

Exception in thread "main" java.lang.NullPointerException
	at Temp.main(Temp.java:7)

Il existe tout un groupe de types d'exceptions dans cette catégorie. Ils sont toujours lancés automatiquement par Java et vous n'avez pas besoin de les inclure dans vos spécifications d'exception. De manière assez pratique, ils sont tous regroupés en les plaçant sous une seule classe de base appelée RuntimeException , qui est un exemple parfait d'héritage : il établit une famille de types qui ont des caractéristiques et des comportements en commun. De plus, vous n'avez jamais besoin d'écrire une spécification d'exception indiquant qu'une méthode peut lever une RuntimeException (ou tout type hérité de RuntimeException ), car ce sont des exceptions non contrôlées. Parce qu'ils indiquent des bogues, vous n'attrapez généralement pas une RuntimeException- c'est traité automatiquement. Si vous étiez obligé de vérifier RuntimeExceptions , votre code pourrait devenir trop compliqué. Même si vous n'attrapez généralement pas les RuntimeExceptions , dans vos propres packages, vous pouvez choisir de lancer certaines des RuntimeExceptions .

Voir les exceptions d'exécution les plus courantes

Bon apprentissage

Rejoindre Mouad Oumous Java WhatsApp Group REJOINDRE

Rejoindre Mouad Oumous Telegram Channel REJOINDRE

Soutenez notre publication en la suivant

GraphQL avec Spring Boot Les erreurs d'exécution Java les plus courantes Premiers pas avec Spring Boot : un didacticiel complet pour les débutants 10 façons simples mais efficaces d'améliorer votre qualité de vie Question d'entrevue basée sur le flux Java8 la plus fréquemment posée - Dernière partie I Gagnez 300 $ en écrivant un livre en 2 jours - Voici comment Qu'est-ce que le chaînage d'exceptions en Java | Gestion des exceptions Comment créer un projet Quarkus simple avec intégration de base de données