Traitement des exceptions non vérifiées

Les méthodes des interfaces définies dans JMS 2.0 émettent des exceptions non vérifiées. La classe de base de ces exceptions est JMSRuntimeException. Par conséquent, l'interception de JMSRuntimeExceptions fournit un moyen générique de traiter ces types d'exceptions.

Chaque JMSRuntimeException encapsule les informations suivantes:
  • Un message d'exception spécifique au fournisseur, que votre application peut obtenir en appelant la méthode JMSRuntimeException.getMessage() .
  • Un code d'erreur spécifique au fournisseur, que votre application peut obtenir en appelant la méthode JMSRuntimeException.getErrorCode() .
  • Une exception associée. Une exception émise par un appel API JMS 2.0 est souvent le résultat d'un problème de niveau inférieur qui est signalé par une autre exception liée à cette exception. Votre application peut obtenir une exception liée en appelant la méthode JMSRuntimeException.getCause() .
Lorsque vous appelez des méthodes sur les interfaces fournies par l'API JMS 2.0 , la plupart des exceptions émises par IBM® MQ classes for JMS sont des instances de sous-classes de JMSRuntimeException. Ces sous-classes implémentent l'interface com.ibm.msg.client.jms.JmsExceptionDetail , qui fournit les informations supplémentaires suivantes:
  • Explication du message d'exception. Votre application peut obtenir ce message en appelant la méthode JmsExceptionDetail.getExplanation() .
  • Une réponse utilisateur recommandée à l'exception. Votre application peut obtenir ce message en appelant la méthode JmsExceptionDetail.getUserAction() .
  • Les clés des insertions de message dans le message d'exception. Votre application peut obtenir un itérateur pour toutes les clés en appelant la méthode JmsExceptionDetail.getKeys() .
  • Les insertions de message dans le message d'exception. Par exemple, une insertion de message peut être le nom de la file d'attente à l'origine de l'exception et il peut être utile pour votre application d'accéder à ce nom. Votre application peut obtenir l'insertion de message correspondant à une clé spécifiée en appelant la méthode JmsExceptionDetail.getValue() .
Toutes les méthodes de l'interface JmsExceptionDetail renvoient la valeur null si aucun détail n'est disponible.
Par exemple, si une application tente de créer un JMSProducer pour une file d'attente IBM MQ qui n'existe pas, une exception est émise avec les informations suivantes:
Message : JMSWMQ2008: Failed to open MQ queue 'Q_test'.
Class : class com.ibm.msg.client.jms.DetailedInvalidDestinationException
Error Code : JMSWMQ2008
Explanation : JMS attempted to perform an MQOPEN, but IBM MQ reported an
              error.
User Action : Use the linked exception to determine the cause of this error. Check
              that the specified queue and queue manager are defined correctly.
L'exception émise, com.ibm.msg.client.jms.DetailedInvalidDestinationException, est une sous-classe de la classe suivante et implémente l'interface com.ibm.msg.client.jms.JmsExceptionDetail .
  • [ Messagerie Jakarta 3.0]jakarta.jms.InvalidDestinationException
  • [ JMS 2.0]javax.jms.InvalidDestinationException

Exceptions chaînées

Généralement, les exceptions sont causées par d'autres exceptions. Par conséquent, pour chaque JMSRuntimeException émise, votre application doit vérifier l'exception liée.

La cause de JMSRuntimeException peut être une autre exception. Ces exceptions forment une chaîne qui renvoie au problème sous-jacent d'origine. La cause d'une exception est implémentée à l'aide du mécanisme d'exception chaînée de la classe java.lang.Throwable et votre application peut obtenir une exception liée en appelant la méthode Throwable.getCause() .

Par exemple, si une application indique un numéro de port incorrect lors de la connexion à un gestionnaire de files d'attente, les exceptions forment la chaîne suivante :
com.ibm.msg.client.jms.DetailIllegalStateException
|
+--->
    com.ibm.mq.MQException
    |
    +--->
        com.ibm.mq.jmqi.JmqiException
        |
        +--->
            com.ibm.mq.jmqi.JmqiException
            |
            +--->
                java.net.ConnectionException
En général, chaque exception d'une chaîne est émise à partir d'une couche différente du code. Par exemple, les exceptions de la chaîne précédente sont émises par les couches suivantes :
  • La première exception, une instance d'une sous-classe de JMSRuntimeException, est émise par la couche commune dans IBM MQ classes for JMS.
  • L'exception suivante, une instance de com.ibm.mq.MQException, est émise par le fournisseur de messagerie IBM MQ .
  • Les deux exceptions suivantes, qui sont toutes deux des instances de com.ibm.mq.jmqi.JmqiException, sont émises par l'interface JMQI ( Java Message Queueing Interface). JMQI est le composant utilisé par IBM MQ classes for JMS pour communiquer avec un gestionnaire de files d'attente.
  • L'exception finale, une instance de java.net.ConnectionException, est émise par la bibliothèque de classes Java .
Pour plus d'informations sur l'architecture en couches de IBM MQ classes for JMS, voir IBM MQ classes for JMS architecture.
Vous pouvez coder votre application pour qu'elle itère à travers cette chaîne afin d'extraire toutes les informations appropriées, comme le montre l'exemple suivant : [ Messagerie Jakarta 3.0]

import com.ibm.msg.client.jms.JmsExceptionDetail;
import com.ibm.mq.MQException;
import com.ibm.mq.jmqi.JmqiException;
import jakarta.jms.JMSRuntimeException;
.
.
.
catch (JMSRuntimeException je) {
  System.err.println("Caught JMSRuntimeException");
  // Check for linked exceptions in JMSRuntimeException
  Throwable t = je;
  while (t != null) {
    // Write out the message that is applicable to all exceptions
    System.err.println("Exception Msg: " + t.getMessage());
    // Write out the exception stack trace
    t.printStackTrace(System.err);

    // Add on specific information depending on the type of exception
    if (t instanceof JMSRuntimeException) {
      JMSRuntimeException je1 = (JMSRuntimeException) t;
      System.err.println("JMS Error code: " + je1.getErrorCode());
      if (t instanceof JmsExceptionDetail){
        JmsExceptionDetail jed = (JmsExceptionDetail)je1;
        System.err.println("JMS Explanation: " + jed.getExplanation());
        System.err.println("JMS Explanation: " + jed.getUserAction());
      }
    } else if (t instanceof MQException) {
      MQException mqe = (MQException) t;
      System.err.println("WMQ Completion code: " + mqe.getCompCode());
      System.err.println("WMQ Reason code: " + mqe.getReason());
    } else if (t instanceof JmqiException){
      JmqiException jmqie = (JmqiException)t;
      System.err.println("WMQ Log Message: " + jmqie.getWmqLogMessage());
      System.err.println("WMQ Explanation: " + jmqie.getWmqMsgExplanation());
      System.err.println("WMQ Msg Summary: " + jmqie.getWmqMsgSummary());
      System.err.println("WMQ Msg User Response: " + jmqie.getWmqMsgUserResponse());
      System.err.println("WMQ Msg Severity: " + jmqie.getWmqMsgSeverity());
    }
    // Get the next cause
    t = t.getCause();
  }
}
[ JMS 2.0]

import com.ibm.msg.client.jms.JmsExceptionDetail;
import com.ibm.mq.MQException;
import com.ibm.mq.jmqi.JmqiException;
import javax.jms.JMSRuntimeException;
.
.
.
catch (JMSRuntimeException je) {
  System.err.println("Caught JMSRuntimeException");
  // Check for linked exceptions in JMSRuntimeException
  Throwable t = je;
  while (t != null) {
    // Write out the message that is applicable to all exceptions
    System.err.println("Exception Msg: " + t.getMessage());
    // Write out the exception stack trace
    t.printStackTrace(System.err);

    // Add on specific information depending on the type of exception
    if (t instanceof JMSRuntimeException) {
      JMSRuntimeException je1 = (JMSRuntimeException) t;
      System.err.println("JMS Error code: " + je1.getErrorCode());
      if (t instanceof JmsExceptionDetail){
        JmsExceptionDetail jed = (JmsExceptionDetail)je1;
        System.err.println("JMS Explanation: " + jed.getExplanation());
        System.err.println("JMS Explanation: " + jed.getUserAction());
      }
    } else if (t instanceof MQException) {
      MQException mqe = (MQException) t;
      System.err.println("WMQ Completion code: " + mqe.getCompCode());
      System.err.println("WMQ Reason code: " + mqe.getReason());
    } else if (t instanceof JmqiException){
      JmqiException jmqie = (JmqiException)t;
      System.err.println("WMQ Log Message: " + jmqie.getWmqLogMessage());
      System.err.println("WMQ Explanation: " + jmqie.getWmqMsgExplanation());
      System.err.println("WMQ Msg Summary: " + jmqie.getWmqMsgSummary());
      System.err.println("WMQ Msg User Response: " + jmqie.getWmqMsgUserResponse());
      System.err.println("WMQ Msg Severity: " + jmqie.getWmqMsgSeverity());
    }
    // Get the next cause
    t = t.getCause();
  }
}
Notez que votre application doit toujours vérifier le type de chaque exception dans une chaîne car le type d'exception peut varier et les exceptions de différents types encapsulent des informations différentes.

Obtention d'informations spécifiques à IBM MQ sur un problème

Les instances de com.ibm.mq.MQException et com.ibm.mq.jmqi.JmqiException encapsulent IBM MQ des informations spécifiques à un problème.

Un MQException encapsule les informations suivantes:
  • Un code achèvement, que votre application peut obtenir en appelant la méthode getCompCode() .
  • Code anomalie que votre application peut obtenir en appelant la méthode getReason() .

Pour des exemples d'utilisation de ces méthodes, voir l'exemple de code dans exceptions chaînées.

Un JmqiException encapsule également un code achèvement et un code anomalie. En outre, un JmqiException contient les informations dans un message AMQ nnnn ou CSQ nnnn , s'il est associé à l'exception. Votre application peut obtenir les différents composants de ce message en appelant les méthodes suivantes:
  • La méthode getWmqMsgExplanation() renvoie l'explication du message AMQ nnnn ou CSQ nnnn .
  • La méthode getWmqMsgSeverity() renvoie la gravité du message AMQ nnnn ou CSQ nnnn .
  • La méthode getWmqMsgSummary() renvoie le récapitulatif du message AMQ nnnn ou CSQ nnnn .
  • La méthode getWmqMsgUserResponse() renvoie la réponse utilisateur associée au message AMQ nnnn ou CSQ nnnn .