Utilisation des extensions IBM JMS

IBM® MQ classes for JMS (JMS 2.0) et IBM MQ classes for Jakarta Messaging (Jakarta Messaging 3.0) contiennent chacun un ensemble d'extensions fonctionnellement identiques à l'API JMS , appelées extensions IBM JMS . Une application peut utiliser ces extensions pour créer des usines de connexion et des destinations de manière dynamique au moment de l'exécution, et pour définir les propriétés des objets IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging . Les extensions peuvent être utilisées avec n'importe quel fournisseur de messagerie.

Les extensions IBM JMS sont un ensemble d'interfaces et de classes dans les packages suivants:
  • com.ibm.msg.client.jms
  • com.ibm.msg.client.services

Pour Jakarta Messaging 3.0, ces packages se trouvent dans com.ibm.jakarta.client.jar.

[ JMS 2.0]Pour JMS 2.0, ces paquets se trouvent dans com.ibm.mqjms.jar ou com.ibm.mq.allclient.jar.

Ces extensions fournissent la fonction suivante:
  • Mécanisme basé sur des fabriques permettant de créer des fabriques de connexions et des destinations de manière dynamique lors de l'exécution, au lieu de les extraire en tant qu'objets gérés à partir d'un espace de nom JNDI ( Java Naming and Directory Interface)
  • Ensemble de méthodes permettant de définir les propriétés des objets IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging
  • Ensemble de classes d'exception avec des méthodes permettant d'obtenir des informations détaillées sur un problème
  • Ensemble de méthodes de contrôle de la fonction de trace
  • Ensemble de méthodes permettant d'obtenir des informations de version sur IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging

Pour la création dynamique de fabriques de connexions et de destinations lors de l'exécution, ainsi que la définition et l'obtention de leurs propriétés, les extensions IBM JMS fournissent un autre ensemble d'interfaces aux extensions IBM MQ JMS . Cependant, alors que les extensions IBM MQ JMS sont spécifiques au fournisseur de messagerie IBM MQ , les extensions IBM JMS ne sont pas spécifiques à IBM MQ et peuvent être utilisées avec n'importe quel fournisseur de messagerie au sein de l'architecture en couches décrite dans IBM MQ classes for JMS architecture.

L'interface com.ibm.msg.client.wmq.WMQConstants (JMS 2.0) ou com.ibm.msg.jakarta.client.wmq.WMQConstants (Jakarta Messaging 3.0) contient les définitions des constantes qu'une application peut utiliser lors de la définition des propriétés des objets IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging à l'aide des extensions IBM JMS . L'interface contient des constantes pour le fournisseur de messagerie IBM MQ et des constantes JMS qui sont indépendantes de tout fournisseur de messagerie.

Les exemples de code qui suivent supposent que les instructions d'importation suivantes sont incluses dans la classe Java :

[ Messagerie Jakarta 3.0]

import com.ibm.msg.jakarta.client.jms.*;
import com.ibm.msg.jakarta.client.services.*;
import com.ibm.msg.jakarta.client.wmq.WMQConstants;
[ JMS 2.0]

import com.ibm.msg.client.jms.*;
import com.ibm.msg.client.services.*;
import com.ibm.msg.client.wmq.WMQConstants;

Création de fabriques de connexions et de destinations

Avant qu'une application puisse créer des usines de connexion et des destinations à l'aide des IBM JMS extensions, elle doit d'abord créer un objet JmsFactoryFactory. Pour créer un objet JmsFactoryFactory, l'application appelle la méthode getInstance( de la classe JmsFactoryFactory, comme le montre l'exemple suivant :

[ Messagerie Jakarta 3.0]

JmsFactoryFactory ff = JmsFactoryFactory.getInstance(JmsConstants.JAKARTA_WMQ_PROVIDER);
[ JMS 2.0]

JmsFactoryFactory ff = JmsFactoryFactory.getInstance(JmsConstants.WMQ_PROVIDER);

Le paramètre de l'appel getInstance() est une constante qui identifie le IBM MQ fournisseur de messagerie comme étant le fournisseur de messagerie choisi. L'application peut ensuite utiliser l'objet JmsFactoryFactory pour créer des usines de connexion et des destinations.

Pour créer une fabrique de connexions, l'application appelle la méthode createConnectionFactory() de l'objet JmsFactoryFactory, comme le montre l'exemple suivant :
JmsConnectionFactory factory = ff.createConnectionFactory();
Cette instruction crée un objet JmsConnectionFactory avec les valeurs par défaut de toutes ses propriétés, ce qui signifie que l'application se connecte au gestionnaire de file d'attente par défaut en mode bindings. Si vous souhaitez qu'une application se connecte en mode client, ou qu'elle se connecte à un gestionnaire de file d'attente autre que le gestionnaire de file d'attente par défaut, l'application doit définir les propriétés appropriées de l'objet JmsConnectionFactory avant de créer la connexion. Pour plus d'informations sur la procédure à suivre, voir Définition des propriétés des classes IBM MQ pour les objets JMS.
La classe JmsFactoryFactory contient également des méthodes permettant de créer des usines de connexion des types suivants :
  • JmsQueueConnectionFactory
  • JmsTopicConnectionFactory
  • JmsXAConnectionFactory
  • JmsXAQueueConnectionFactory
  • JmsXATopicConnectionFactory
Pour créer un objet Queue, l'application appelle la méthode createQueue() de l'objet JmsFactoryFactory, comme le montre l'exemple suivant :
JmsQueue q1 = ff.createQueue("Q1");
Cette instruction crée un objet JmsQueue avec les valeurs par défaut pour toutes ses propriétés. L'objet représente une file d'attente IBM MQ appelée Q1 qui appartient au gestionnaire de files d'attente local. Cette file d'attente peut être une file d'attente locale, une file d'attente alias ou une définition de file d'attente éloignée.
La méthode createQueue() peut également accepter un identifiant de ressource uniforme (URI) de file d'attente comme paramètre. Un URI de file d'attente est une chaîne qui spécifie le nom d'une file d'attente IBM MQ et, en option, le nom du gestionnaire de files d'attente propriétaire de la file d'attente, ainsi qu'une ou plusieurs propriétés de l'objet JmsQueue . L'instruction suivante contient un exemple d'URI de file d'attente:
JmsQueue q2 = ff.createQueue("queue://QM2/Q2?persistence=2&priority=5");
L'objet JmsQueue créé par cette instruction représente une file d'attente IBM MQ appelée Q2 qui appartient au gestionnaire de files d'attente QM2, et tous les messages envoyés à cette destination sont persistants et ont une priorité de 5. Pour plus d'informations sur les URI de file d'attente, voir URI (Uniform Resource Identifier). Pour une autre méthode de définition des propriétés d'un objet JmsQueue , voir Définition des propriétés des objets IBM MQ classes for JMS.
Pour créer un objet Topic, une application peut utiliser la méthode createTopic() de l'objet JmsFactoryFactory, comme le montre l'exemple suivant :
JmsTopic t1 = ff.createTopic("Sport/Football/Results");
Cette instruction crée un objet JmsTopic avec les valeurs par défaut pour toutes ses propriétés. L'objet représente un sujet appelé Sport / Football/Résultats.
La méthode createTopic() peut également accepter un URI de sujet comme paramètre. Un URI de rubrique est une chaîne qui spécifie le nom d'une rubrique et, en option, une ou plusieurs propriétés de l'objet JmsTopic . Les instructions suivantes contiennent un exemple d'URI de rubrique:
String s1 = "topic://Sport/Tennis/Results?persistence=1&priority=0";
JmsTopic t2 = ff.createTopic(s1);
L'objet JmsTopic créé par ces instructions représente une rubrique appelée Sport / Tennis/Results, et tous les messages envoyés à cette destination sont non persistants et ont une priorité de 0. Pour plus d'informations sur les URI de rubrique, voir URI (Uniform Resource Identifier). Pour une autre méthode de définition des propriétés d'un objet JmsTopic , voir Définition des propriétés des objets IBM MQ classes for JMS.

Une fois qu'une application a créé une fabrique de connexions ou une destination, cet objet ne peut être utilisé qu'avec le fournisseur de messagerie sélectionné.

Définition des propriétés des objets IBM MQ classes for JMS

Pour définir les propriétés des objets IBM MQ classes for JMS à l'aide des extensions IBM JMS , une application utilise les méthodes de l'interface com.ibm.msg.client.JmsPropertyContext . De même, pour définir les propriétés des objets IBM MQ classes for Jakarta Messaging à l'aide des extensions IBM JMS , une application utilise les méthodes de l'interface com.ibm.msg.jakarta.client.JmsPropertyContext .

Pour chaque Java type de données, l'interface JmsPropertyContext contient une méthode pour définir la valeur d'une propriété avec ce type de données, et une méthode pour obtenir la valeur d'une propriété avec ce type de données. Par exemple, une application appelle la méthode setIntProperty() pour définir une propriété avec une valeur entière, et appelle la méthode getIntProperty() pour obtenir une propriété avec une valeur entière.

Les instances des classes des paquets com.ibm.mq.jms et com.ibm.mq.jakarta.jms héritent des méthodes des interfaces JmsPropertyContext correspondantes. Une application peut donc utiliser ces méthodes pour définir les propriétés des objets MQConnectionFactory, MQQueue et MQTopic.

Lorsqu'une application crée un objet IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging , toutes les propriétés avec des valeurs par défaut sont définies automatiquement. Lorsqu'une application définit une propriété, la nouvelle valeur remplace toute valeur précédente de la propriété. Une fois qu'une propriété a été définie, elle ne peut pas être supprimée, mais sa valeur peut être modifiée.

Si une application tente de définir une propriété sur une valeur qui n'est pas une valeur valide pour la propriété, IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging émet une exception JMSException. Si une application tente d'obtenir une propriété qui n'a pas été définie, le comportement est décrit dans la spécification JMS . IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging throw a NumberFormatException exception for primitive data types and return null for referenced data types.

Outre les propriétés prédéfinies d'un objet IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging , une application peut définir ses propres propriétés. Ces propriétés définies par l'application sont ignorées par IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging.

Pour plus d'informations sur les propriétés des objets IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging , voir Propriétés des objets IBM MQ classes for JMS.

Le code suivant est un exemple de définition des propriétés à l'aide des extensions IBM JMS . Le code définit cinq propriétés d'une fabrique de connexions.
factory.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE,
WMQConstants.WMQ_CM_CLIENT);
factory.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "QM1");
factory.setStringProperty(WMQConstants.WMQ_HOST_NAME, "HOST1");
factory.setIntProperty(WMQConstants.WMQ_PORT, 1415);
factory.setStringProperty(WMQConstants.WMQ_CHANNEL, "QM1.SVR");
factory.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "My Application");
La définition de ces propriétés a pour effet que l'application se connecte au gestionnaire de files d'attente QM1 en mode client, à l'aide d'un canal MQI appelé QM1.SVR. Le gestionnaire de files d'attente s'exécute sur un système dont le nom d'hôte est HOST1et le programme d'écoute du gestionnaire de files d'attente est en mode écoute sur le port 1415. Cette connexion et les autres connexions de gestionnaire de files d'attente associées aux sessions qui la contiennent sont associées au nom d'application "Mon application".
Remarque: Les gestionnaires de files d'attente s'exécutant sur des plateformes z/OS® ne prennent pas en charge la définition des noms d'application et ce paramètre est donc ignoré.
L'interface JmsPropertyContext contient également la méthode setObjectProperty(), qu'une application peut utiliser pour définir des propriétés. Le second paramètre de la méthode est un objet qui encapsule la valeur de la propriété. Par exemple, le code suivant crée un objet Integer qui encapsule l'entier 1415, puis appelle setObjectProperty() pour définir la propriété PORT d'une fabrique de connexions à la valeur 1415 :
Integer port = new Integer(1415);
factory.setObjectProperty(WMQConstants.WMQ_PORT, port);
Ce code est donc équivalent à l'instruction suivante:
factory.setIntProperty(WMQConstants.WMQ_PORT, 1415);

Inversement, la méthode getObjectProperty() renvoie un objet qui encapsule la valeur d'une propriété.

Conversion implicite d'une valeur de propriété d'un type de données à un autre

Lorsqu'une application utilise une méthode de l'interface JmsPropertyContext pour définir ou obtenir la propriété d'un objet IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging, la valeur de la propriété peut être implicitement convertie d'un type de données à un autre.

Par exemple, l'instruction suivante définit la propriété PRIORITY de l'objet JmsQueue q1:
q1.setStringProperty(WMQConstants.WMQ_PRIORITY, "5");
La propriété PRIORITY ayant une valeur entière, l'appel setStringProperty() convertit implicitement la chaîne 5 (la valeur source) en un nombre entier 5 (la valeur cible), qui devient alors la valeur de la propriété PRIORITY.
A l'inverse, l'instruction suivante extrait la propriété PRIORITY de l'objet JmsQueue q1:
String s1 = q1.getStringProperty(WMQConstants.WMQ_PRIORITY);
L'entier 5 (la valeur source), qui est la valeur de la propriété PRIORITY, est implicitement converti en chaîne 5 (la valeur cible) par l'appel getStringProperty().

Les conversions prises en charge par IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging sont présentées dans le Tableau 1.

Tableau 1. Conversions prises en charge d'un type de données à un autre
Type de données source Types de données cible pris en charge
boolean String
byte int, long, court, Chaîne
char String
double String
float double, chaîne
int long, chaîne
long String
short int, long, Chaîne
String booléen, octet, double, flotteur, int, long, court
Les règles générales régissant les conversions prises en charge sont les suivantes:
  • Les valeurs numériques peuvent être converties d'un type de données à un autre, à condition qu'aucune donnée ne soit perdue lors de la conversion. Par exemple, une valeur avec le type de données int peut être convertie en une valeur avec le type de données long, mais ne peut pas être convertie en une valeur avec le type de données short.
  • Une valeur de n'importe quel type de données peut être convertie en chaîne.
  • Une chaîne peut être convertie en une valeur de tout autre type de données (sauf char ) à condition que la chaîne soit au format correct pour la conversion. Si une application tente de convertir une chaîne qui n'est pas dans le bon format, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging lance une exception NumberFormatException.
  • Si une application tente une conversion qui n'est pas prise en charge, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging lance une exception MessageFormatException.
Les règles spécifiques de conversion d'une valeur d'un type de données à un autre sont les suivantes:
  • Lors de la conversion d'une valeur booléenne en chaîne, la valeur true est convertie en chaîne trueet la valeur false est convertie en chaîne false.
  • Lors de la conversion d'une chaîne en valeur booléenne, la chaîne true (non sensible à la casse) est convertie en trueet la chaîne false (non sensible à la casse) est convertie en false. Toute autre chaîne est convertie en false.
  • Lors de la conversion d'une chaîne en une valeur avec le type de données byte, int, longou short, la chaîne doit avoir le format suivant:
    • [ blancs ] [ signe ] chiffres
    Les significations des composants de la chaîne sont les suivantes:
    blancs
    Caractères blancs facultatifs de début.
    signer
    Signe plus (+) ou signe moins (-) facultatif.
    chiffres
    Séquence contiguë de chiffres (0-9). Au moins un chiffre doit être présent.

    Après la séquence de chiffres, la chaîne peut contenir d'autres caractères qui ne sont pas des chiffres, mais la conversion s'arrête dès que le premier de ces caractères est atteint. La chaîne est supposée représenter un entier décimal.

    Si la chaîne n'est pas au bon format, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging lance une exception NumberFormatException.

  • Lors de la conversion d'une chaîne en une valeur avec le type de données double ou float, la chaîne doit avoir le format suivant:
    • [ blancs ] [ signe ] chiffres [ e_char [ e_signe ] e_digits ]
    Les significations des composants de la chaîne sont les suivantes:
    blancs
    Caractères blancs facultatifs de début.
    signer
    Signe plus (+) ou signe moins (-) facultatif.
    chiffres
    Séquence contiguë de chiffres (0-9). Au moins un chiffre doit être présent.
    _char
    Caractère exposant, qui peut être E ou e.
    _signe
    Signe plus (+) ou signe moins (-) facultatif pour l'exposant.
    e_chiffres
    Séquence contiguë de chiffres (0-9) pour l'exposant. Au moins un chiffre doit être présent si la chaîne contient un caractère d'exposant.

    Après la séquence de chiffres ou les caractères facultatifs représentant un exposant, la chaîne peut contenir d'autres caractères qui ne sont pas des chiffres, mais la conversion s'arrête dès que le premier de ces caractères est atteint. La chaîne est supposée représenter un nombre décimal en virgule flottante avec un exposant puissance de 10.

    Si la chaîne n'est pas au bon format, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging lance une exception NumberFormatException.

  • Lors de la conversion d'une valeur numérique (y compris une valeur avec le type de données byte ) dans une chaîne, la valeur est convertie en représentation de chaîne de la valeur sous la forme d'un nombre décimal, et non la chaîne contenant le caractère ASCII pour cette valeur. Par exemple, l'entier 65 est converti en chaîne 65, et non en chaîne A.

Définition de plusieurs propriétés dans un même appel

L'interface JmsPropertyContext contient également la méthode setBatchProperties(), qu'une application peut utiliser pour définir plusieurs propriétés en un seul appel. Le paramètre de la méthode est un objet Map qui encapsule un ensemble de paires nom-valeur de propriété.

Par exemple, le code suivant utilise la méthode setBatchProperties() pour définir les cinq mêmes propriétés d'une fabrique de connexions que celles présentées dans la section Définition des propriétés des classes IBM MQ pour les objets JMS. Le code crée une instance de la classe HashMap , qui implémente l'interface Map.
HashMap batchProperties = new HashMap();
batchProperties.put(WMQConstants.WMQ_CONNECTION_MODE,
                    new Integer(WMQConstants.WMQ_CM_CLIENT));
batchProperties.put(WMQConstants.WMQ_QUEUE_MANAGER, "QM1");
batchProperties.put(WMQConstants.WMQ_WMQ_HOST_NAME, "HOST1");
batchProperties.put(WMQConstants.WMQ_PORT, "1414");
batchProperties.put(WMQConstants.WMQ_CHANNEL, "QM1.SVR");
factory.setBatchProperties(batchProperties);
Notez que le second paramètre de la méthode Map.put() doit être un objet. Par conséquent, une valeur de propriété avec un type de données primitif doit être encapsulée dans un objet ou représentée par une chaîne, comme illustré dans l'exemple.

La méthode setBatchProperties() valide chaque propriété. Si la méthode setBatchProperties() ne peut pas définir une propriété parce que, par exemple, sa valeur n'est pas valide, aucune des propriétés spécifiées n'est définie.

Noms et valeurs de propriété

Si une application utilise les méthodes de l'interface JmsPropertyContext appropriée pour définir et obtenir les propriétés des objets IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging, l'application peut spécifier les noms et les valeurs des propriétés de l'une des manières suivantes. Chacun des exemples qui l'accompagnent montre comment définir la propriété PRIORITY de l'objet JmsQueue q1 de sorte qu'un message envoyé à la file d'attente ait la priorité spécifiée dans l'appel send ().
Utilisation des noms et des valeurs de propriété définis en tant que constantes dans l'interface com.ibm.msg.client.wmq.WMQConstants
L'instruction suivante est un exemple de spécification des noms et des valeurs des propriétés de cette manière:
q1.setIntProperty(WMQConstants.WMQ_PRIORITY, WMQConstants.WMQ_PRI_APP);
Utilisation des noms et des valeurs de propriété pouvant être utilisés dans les identificateurs URI (Uniform Resource Identifier) de file d'attente et de rubrique
L'instruction suivante est un exemple de spécification des noms et des valeurs des propriétés de cette manière:
q1.setIntProperty("priority", -2);

Seuls les noms et les valeurs des propriétés des destinations peuvent être spécifiés de cette manière.

Utilisation des noms et des valeurs de propriété reconnus par l'outil d'administration de IBM MQ JMS
L'instruction suivante est un exemple de spécification des noms et des valeurs des propriétés de cette manière:
q1.setStringProperty("PRIORITY", "APP");
La forme abrégée du nom de propriété est également acceptable, comme indiqué dans l'instruction suivante:
q1.setStringProperty("PRI", "APP");
Lorsqu'une application obtient une propriété, la valeur renvoyée dépend de la manière dont l'application spécifie le nom de la propriété. Par exemple, si une application spécifie la constante WMQConstants.WMQ_PRIORITY comme nom de propriété, la valeur renvoyée est l'entier -2
int n1 = getIntProperty(WMQConstants.WMQ_PRIORITY);
La même valeur est renvoyée si l'application spécifie la chaîne "priority" comme nom de propriété:
int n2 = getIntProperty("priority");
Toutefois, si l'application spécifie la chaîne "PRIORITY" ou "PRI" comme nom de propriété, la valeur renvoyée est la chaîne "APP":
String s1 = getStringProperty("PRI");

En interne, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging stockent les noms et les valeurs des propriétés en tant que valeurs littérales définies dans l'interface WMQConstants correspondante. Il s'agit du format canonique défini pour les noms et les valeurs de propriété. En règle générale, si une application définit des propriétés à l'aide de l'une des deux autres méthodes de spécification des noms et des valeurs de propriété, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging doivent convertir les noms et les valeurs du format d'entrée spécifié au format canonique. De même, si une application obtient des propriétés à l'aide de l'une des deux autres méthodes de spécification des noms et des valeurs de propriété, IBM MQ classes for JMS et IBM MQ classes for Jakarta Messaging doivent convertir les noms du format d'entrée spécifié dans le format canonique et convertir les valeurs du format canonique dans le format de sortie requis. L'exécution de ces conversions peut avoir des conséquences sur les performances.

Les noms de propriété et les valeurs renvoyés par les exceptions, dans les fichiers de trace ou dans le journal IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging , sont toujours au format canonique.

Utilisation de l'interface Map

L'interface JmsPropertyContext étend l'interface java.util.Map Une application peut donc utiliser les méthodes de l'interface Map pour accéder aux propriétés d'un objet IBM MQ classes for JMS ou IBM MQ classes for Jakarta Messaging .

Par exemple, le code suivant imprime les noms et les valeurs de toutes les propriétés d'une fabrique de connexions. Le code utilise uniquement les méthodes de l'interface Map pour obtenir les noms et les valeurs des propriétés.
// Get the names of all the properties
Set propNames = factory.keySet();

// Loop round all the property names and get the property values
Iterator iterator = propNames.iterator();
while (iterator.hasNext()){
    String pName = (String)iterator.next();
    System.out.println(pName+"="+factory.get(pName));
}

L'utilisation des méthodes de l'interface de mappe ne permet pas de contourner les validations de propriété ou les conversions.