Exceptions de chargement de classes

Quel type d'erreur de chargement de classes s'affiche-t-il lors du développement d'une application ou au démarrage d'une application installée ?

ClassCastException

Une exception de transtypage de classe se produit dans les conditions suivantes et peut être corrigée au moyen des actions ci-dessous :

Le type d'objet source n'est pas une instance de la classe cible (type).
Il s'agit d'une exception de transtypage de classe typique. Vous pouvez diagnostiquer si l'objet source d'une instruction de transtypage n'est pas une instance de classe cible (type) en examinant la signature de classe, puis en vérifiant s'il ne contient pas la classe cible dans son ascendance et que la classe d'objet source est différente de la classe cible. Vous pouvez obtenir des informations de classe en insérant une simple instruction d'impression dans votre code. Par exemple :
System.out.println( source.getClass().getName() + “:” + target.getClass().getName() );
ou utiliser une commande javap. Par exemple :
javap java.util.HashMap
Compiled from "HashMap.java"
public class java.util.HashMap extends java.util.AbstractMap
             implements java.util.Map,java.lang.Cloneable,java.io.Serializable {
Le chargeur de classe ayant chargé l'objet source (classe) est différent du chargeur de classe ayant chargé la classe cible.
Considérant que le type d'objet source est une instance de la classe cible, une exception de transtypage de classe se produit lorsque le chargeur de classe ayant chargé la classe de l'objet source est différent du chargeur de classe ayant chargé l'objet cible. Cette condition peut se produire lorsque la classe de cible est visible sur les chemins d'accès aux classes de plusieurs chargeurs de classe dans l'environnement d'exécution WebSphere Application Server. Pour corriger cet incident, utilisez les pages de la console Rechercher et Rechercher par nom de classe pour identifier les problèmes liés aux chargeurs de la classe :
  1. Cliquez sur Résolution des incidents > Afficheur de chargeur de classe > nom_module > Rechercher pour accéder à la page Rechercher.
  2. Pour Type de recherche, sélectionnez Classe/Package.
  3. Pour Rechercher des termes, tapez le nom de la classe chargée par deux chargeurs de classe.
  4. Cliquez sur OK. La page Rechercher par nom de classe s'affiche et répertorie tous les chargeurs de classe qui chargent cette classe.

    S'il existe plusieurs chargeurs de classe répertoriés, la classe cible est chargée par plusieurs chargeurs de classe. Le type d'objet source étant une instance de la classe cible, le chargeur de classe ayant chargé la classe de l'objet source est différent du chargeur de classe ayant chargé l'objet cible.

  5. Retournez sur la page Afficheur de chargeur de classe et examinez le chemin d'accès aux classes pour déterminer pourquoi deux chargeurs de classe différents chargent cette classe.
  6. Corrigez votre code de telle sorte que la classe soit visible uniquement pour le chargeur de classe approprié.
L'application ne parvient pas à effectuer correctement l'opération narrow.
Une exception de transtypage de classe peut se produire, lorsque l'application résoud un objet EJB, le code de l'application n'effectue pas d'opération de conversion (narrow) comme requis. Le code doit effectuer une telle opération après la recherche d'un objet distant. Examinez l'application et déterminez si elle recherche un objet distant, si c'est le cas, le résultat de la recherche est soumis à une méthode narrow.

La méthode narrow doit être invoquée selon le modèle de programmation EJB 2.0. En particulier, la classe cible soumise à la méthode narrow doit être l'exacte, interface presque dérivée de l'EJB. Cela provoque également une exception de transtypage de classe dans l'environnement d'exécution WebSphere Application Server. Examinez l'application et déterminez si la classe cible soumise à la méthode soumise est une super interface de l'EJB spécifié, pas le type exact de l'EJB ; si c'est le cas, modifiez l'application de sorte qu'elle appelle la méthode narrow avec l'interface EJB exacte.

Enfin, si une exception de transtypage de classe se produit pendant une opération narrow, vérifiez que la méthode narrow est appliquée au résultat d'une recherche sur un EJB distant, pas sur un bean enterprise local. Ce type d'opération ne peut pas être utilisé pour des recherches locales. Examinez le descripteur de déploiement du module ou de l'application pour vous assurer que l'objet en cours de conversion n'est pas un objet local.

ClassNotFoundException

Une exception de classe non trouvée se produit dans les conditions suivantes et peut être corrigée au moyen des actions ci-dessous :

Cette classe n'est pas visible sur le chemin d'accès aux classes logique du chargeur de classe de contexte.
La classe non trouvée ne se trouve pas dans le chemin d'accès aux classes logique du chargeur de classe associé à l'unité d'exécution actuelle. Le chemin d'accès aux classes est l'accumulation de tous les chemins d'accès aux classes ayant fait l'objet d'une recherche lorsque l'opération de chargement a été appelée sur un chargeur de classe. Pour corriger cet incident, utilisez la page Rechercher afin d'effectuer une recherche par nom de classe et par nom JAR (Java™ archive) :
  1. Cliquez sur Résolution des incidents > Afficheur de chargeur de classe > nom_module > Rechercher pour accéder à la page Rechercher.
  2. Pour Type de recherche, sélectionnez Classe/Package.
  3. Pour Chaîne de recherche, tapez le nom de classe non trouvée.
  4. Cliquez sur OK. La page Rechercher par nom de classe s'affiche et répertorie tous les chargeurs de classe qui chargent cette classe.
  5. Examinez la page pour voir si la classe existe dans la liste.
  6. Si elle ne figure pas dans la liste, retournez à la page Rechercher. Pour Rechercher des termes, tapez le nom du fichier .jar de la classe ; pour Type de recherche, sélectionnez Fichier JAR/Répertoire.
  7. Cliquez sur OK. La page Rechercher par chemin est affichée, énumérant tous les répertoires contenant le fichier JAR.

Si le fichier JAR ne figure pas dans la liste, pareillement la classe ne se trouve pas dans le chemin d'accès aux classes logique, est illisible ou une autre classe est déjà chargée. Déplacez la classe vers un emplacement lui permettant d'être chargée.

L'application utilise de façon incorrecte une API de chargeur de classe.
Une application peut obtenir une instance d'un chargeur de classe et appeler soit la méthode loadClass sur ce chargeur, soit la classe Class.forName(nom_classe, initialize, chargeur_classe) avec ce chargeur de classe. Il se peut que l'application utilise incorrectement l'interface API du chargeur de classe. Par exemple, le nom de classe est incorrect, la classe n'est pas visible sur le chemin d'accès aux classes logique de ce chargeur de classe ou encore le chargeur de classe pris n'est pas le bon.

Pour résoudre ce problème, déterminez si la classe existe et si l'application utilise correctement l'interface API du chargeur de classe. Suivez les étapes de La classe n'est pas visible sur le chemin d'accès aux classes logiques du chargeur de classe de contexte pour déterminer si la classe est chargée. Si la classe n'a pas été chargée, tentez de corriger l'application et vérifiez si la classe se charge. Si la classe figure dans le chemin d'accès aux classes et est dotée des droits appropriés, et n'est pas remplacée par une autre classe de fabrique, vérifiez l'API utilisée pour charger la classe.

  1. Cliquez sur Résolution des incidents > Afficheur de chargeur de classe > nom_module > Rechercher pour accéder à la page Rechercher du chargeur de classe.
  2. Pour Type de recherche, sélectionnez Classe/Package.
  3. Pour Rechercher des termes, entrez le nom de la classe.
  4. Cliquez sur OK. La page Rechercher par nom de classe s'affiche et répertorie tous les chargeurs de classe qui chargent cette classe.
  5. Examinez la page pour voir si la classe existe dans la liste.
  6. Si la classe figure dans la liste et qu'une exception ClassNotFound a été lancée, le fichier .jar ou la classe ne figure pas dans le contexte approprié et un appel d'API incorrect a été utilisé dans le contexte en cours.
    Si elle ne figure pas dans la liste, retournez à la page Rechercher et procédez comme suit :
    1. Recherchez la classe qui a généré l'exception, autrement dit la classe appelant Class.forName.
    2. Vérifiez quel chargeur de classe charge la classe.
    3. Déterminez quel chargeur de classe a accès à la classe non trouvée ou peut la charger en évaluant le chemin d'accès aux classes du chargeur de classe.
Une classe dépendante n'est pas visible.
Lorsqu'un chargeur de classe clsldr charge une classe cls, la machine JVM invoque clsldr pour charger les classes dont cls dépend. Les classes dépendantes doivent être visibles dans le chemin d'accès aux classes logique de clsldr, sinon, il se produit une exception. Cette condition intervient généralement lorsque les utilisateurs rendent les classes WebSphere Application Server visibles à la machine virtuelle Java ou rendent des classes de l'application visibles au chargeur de classe des extensions WebSphere. Par exemple :
  • La Classe A dépend de la Classe B.
  • Le chargeur de classe d'extensions WebSphere peut voir la Classe A.
  • La classe B est visible sur le chemin d'accès aux classes local d'un chargeur de classe de module WAR, pas sur le chemin d'accès aux classes du chargeur de classes des extensions WebSphere.

Lorsque la machine JVM charge une classe A à l'aide du chargeur de classe des extensions WebSphere, elle tente ensuite de charger la classe B à l'aide du même chargeur de classe, et elle finit par créer une exception de classe non trouvée.

Pour résoudre le problème, procédez comme suit :

  1. Rendez les classes spécifiques à l'application visibles au chargeur de classe de l'application.
  2. Cherchez la classe non trouvée (Classe B).
  3. Si la Classe B figure à l'emplacement approprié, recherchez la classe qui charge la classe dépendante (Classe A) dans l'Afficheur des chargeurs de classe.
  4. Si la classe est chargée et qu'une exception ClassNotFound a été lancée, cela signifie que le fichier .jar ou la classe ne figure pas dans le contexte approprié ou qu'un appel d'API incorrect a été utilisé dans le contexte en cours.
    Si aucune classe n'a été trouvée, procédez comme suit :
    1. Recherchez la classe qui a généré l'exception, autrement dit la classe appelant Class.forName.
    2. Vérifiez quel chargeur de classe charge la classe.
    3. Déterminez quel chargeur de classe a accès à la classe non trouvée ou peut la charger en évaluant le chemin d'accès aux classes du chargeur de classe.
  5. Assurez-vous que la JVM ou le chargeur de classe d'extensions WebSphere peut voir la classe appelante (Classe B).

NoClassDefFoundException

Une exception "aucune définition de classe trouvée" est lancée lorsque les conditions suivantes existent et peut être corrigée par les actions suivantes :

La classe ne se trouve pas dans le chemin d'accès logique.
Pour plus d'informations, voir ClassNotFoundException.
La classe ne peut pas se charger.
Plusieurs causes peuvent être à l'origine du non chargement de la classe. Parmi lesquelles : échec du chargement de la classe dépendante, format de la classe dépendante erroné ou numéro de version d'une classe.

UnsatisfiedLinkError

Une erreur de liaison est entraînée lorsque les conditions suivantes existent et peut être corrigée par les actions ci-dessous :

Une intervention de l'utilisateur a entraîné l'erreur.

Plusieurs interventions de l'utilisateur peuvent entraîner une erreur de liaison :

Un nom d'extension de bibliothèque est incorrect pour la plateforme.

[Windows]Une bibliothèque porte le nom de bibliothèque DDL (Dynamic Link Library) nom_bibliothèque.dll.

[AIX HP-UX Solaris]Une bibliothèque porte le nom nom_bibliothèque.so ou nom_bibliothèque.a.

System.loadLibrary reçoit un paramètre incorrect.

[Windows]Pour charger une bibliothèque DDL nommée Nom.dll, Nom doit être transmis à un appel loadLibrary.

[AIX HP-UX Solaris]Pour charger une bibliothèque nommée nomBib.so ou nomBib.a, nomBib est transmis à la bibliothèque de modules de chargement.

La bibliothèque n'est pas visible.
Le plus judicieux est d'utiliser le chargeur de classe JVM pour chercher ou charger des bibliothèques natives. WebSphere Application Server imprime le chemin de la bibliothèque Java (java.library.path) au démarrage. Si le chargeur de classe JVM est censé charger la bibliothèque, vérifiez que le chemin contenant le fichier de bibliothèque natif se trouve dans le chemin de la bibliothèque Java. Si ce n'est pas le cas, ajoutez le chemin à la variable d'environnement de la bibliothèque native spécifique à la plateforme, ou à la propriété système java.library.path de la définition du processus serveur.

Généralement, la machine virtuelle Java invoque findLibrary() sur le chargeur de classe xxx qui charge la classe appelant System.loadLibrary(). Si xxx.findLibrary() échoue, la machine virtuelle Java tente de trouver la bibliothèque à l'aide du chargeur de classe de la JVM qui recherche le chemin d'accès à la bibliothèque de la JVM. Si la bibliothèque est introuvable, la machine virtuelle Java crée une erreur UnsatisfiedLinkError.

Par conséquent, si un chargeur de classe WebSphere est censé rechercher une bibliothèque native myNativeLib, la bibliothèque doit être visible sur le nativelibpath du chargeur de classe qui charge la classe qui appelle System.loadLibrary(myNativeLib). Cette procédure est nécessaire et souhaitable dans les situations suivantes :

  • [z/OS]Les bibliothèques natives des fournisseurs de sources de données doivent être visibles sur le nativelibpath du chargeur de classe des extensions WebSphere. Dans ce cas, ajoutez le chemin contenant la librairie native au paramètre Chemin d'accès aux bibliothèques natives de la configuration du fournisseur de sources de données.
  • Les bibliothèques partagées disposent d'un Chemin d'accès aux bibliothèques natives dans leur configuration. Etant donné que les bibliothèques partagées appliquent la gestion des versions des bibliothèques spécifiques à l'application, pensez à spécifier les chemins vers d'autres bibliothèques natives utilisées par le code de la bibliothèque partagée dans la configuration de la bibliothèque partagée.

Assurez-vous que le chargeur de classe WebSphere correct charge la classe qui appelle System.loadLibrary() et que la bibliothèque native est visible dans le paramètre Chemin d'accès aux bibliothèques natives.

[AIX HP-UX Solaris]
System.mapLibraryName renvoie un fichier de bibliothèque erroné.
Lors du chargement d'une bibliothèque partagée, la JVM appelle mapLibraryName(nomBib) pour convertir nomLib en nom spécifique à une plateforme. Sur les systèmes d'exploitation AIX, HP-UX ou Solaris, cet appel peut renvoyer un nom de fichier avec la mauvaise extension (par exemple, libName.so au lieu de libName.a). Pour régler ce problème, écrivez un programme pour ces appels System.mapLibraryName() et vérifiez qu'il renvoie le nom de fichier correct.
La bibliothèque native est déjà chargée.
Cette condition peut entraîner l'une des erreurs suivantes :
Erreur de l'utilisateur
Vérifiez les multiples appels vers System.loadLibrary et supprimez les appels sans rapport avec ceci.
Erreur lors du redémarrage d'une application
La machine virtuelle Java dispose d'une restriction qui empêche un chargeur de classe de charger plus d'une bibliothèque native à la fois. Une erreur est générée lorsqu'une application redémarre avant que le récupérateur de place ne nettoie le chargeur de classe de l'application arrêtée. Lorsque la classe qui charge la bibliothèque native est déplacée, toutes les classes qui dépendent de cette bibliothèque native et leurs dépendances doivent aussi être déplacées.

Pour outrepasser cette condition, déplacer le chargement de la bibliothèque native vers un chargeur de classe qui ne se recharge pas :

  1. Localisez toutes les classes de l'application qui chargent des bibliothèques natives ou disposent de méthodes natives.
  2. Identifiez toutes les classes de dépendants des classes de l'étape 1, comme les packages de journalisation.
  3. Créez une bibliothèque partagée dont la portée est le serveur ou une bibliothèque partagée isolée.
  4. Déplacez les fichiers JAR chargés pour les classes des étapes 1 et 2 de l'application vers la bibliothèque partagée créée à l'étape 3.
  5. Sauvegardez les modifications.
  6. Redéployez l'application et exécutez à nouveau le scénario.

Les classes au sein de bibliothèques dont la portée est le serveur sont chargées une fois pour chaque cycle de vie du serveur, garantissant ainsi que la bibliothèque native requise par l'application soit chargée une fois pour chaque machine virtuelle Java, quel que soit le cycle de vie de l'application.

Une bibliothèque native dépendante a été utilisée.
Les bibliothèques natives dépendantes doivent être trouvées ou chargées par le chargeur de classe de la JVM. Autrement dit, si une bibliothèque native NL est dépendante d'une autre bibliothèque native, DNL, le chargeur de classe de la JVM doit trouver DNL dans le chemin d'accès à la bibliothèque Java. Ceci est dû au fait que la machine virtuelle Java exécute le code natif lors du chargement de NL. Ainsi lorsqu'il rencontre la dépendance envers DNL, le code natif de la JVM ne peut appeler que le chargeur de classe de la JVM pour résoudre la dépendance. Un chargeur de classe WebSphere ne peut pas charger une bibliothèque native dépendante.

Modifiez la variable d'environnement définissant le chemin d'accès à la bibliothèque (LIBPATH) spécifique à la plateforme pour inclure le chemin d'accès contenant la bibliothèque native non résolue.


Icône indiquant le type de rubrique Rubrique de référence



Icône d'horodatage Dernière mise à jour: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=rtrb_classload_viewer
Nom du fichier : rtrb_classload_viewer.html