Java/PCF Program to Create an IBM MQ SVRCONN Channel

A couple of weeks ago, I posted a Java/PCF Program to Create an IBM MQ Queue. So, today I thought I would create a Java/PCF program to create an IBM MQ SVRCONN channel

If you are used to creating an IBM MQ channel using runmqsc command then the following simple Java/PCF program will create a IBM MQ channel based on the following runmqsc command:

DEFINE CHL('ABC.CHL') MAXMSGL(10485760) SCYEXIT('C:\Capitalware\MQCCI\mqcci(CCI)') SCYDATA('mqcci.ini')

Note: For the channel security exit, I used Capitalware’s MQ Channel Connection Inspector (MQCCI) product. MQCCI is a solution that allows a company to track and/or audit what information a client application or remote queue manager is exchanging with the queue manager when a connection is made.

You can download the source code from here.

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import com.ibm.mq.MQException;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;

/**
 * Program Name
 *  MQCreateChannel01
 *
 * Description
 *  This java class issues a PCF "create channel" request message that will create a SVRCONN channel 
 *  specifying max message length & channel security exit.  
 *  For the channel security exit, I used Capitalware's MQ Channel Connection Inspector (MQCCI) product.
 *  MQCCI is a solution that allows a company to track and/or audit what information a client application 
 *  or remote queue manager is exchanging with the queue manager when a connection is made. 
 *  
 *  This PCF code is equivalent to issuing the runmqsc command of:
 *     DEFINE CHL('ABC.CHL') MAXMSGL(10485760) SCYEXIT('C:\Capitalware\MQCCI\mqcci(CCI)') SCYDATA('mqcci.ini')
 *
 * Sample Command Line Parameters
 *  -m MQA1 -z TEST.CHL -h 127.0.0.1 -p 1414 -c TEST.CHL -u UserID -x Password
 *
 * @author Roger Lacroix
 */
public class MQCreateChannel01
{
   private static final SimpleDateFormat  LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");

   private Hashtable<String,String> params;
   private Hashtable<String,Object> mqht;

   public MQCreateChannel01()
   {
      super();
      params = new Hashtable<String,String>();
      mqht = new Hashtable<String,Object>();
   }

   /**
    * Make sure the required parameters are present.
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-h") && params.containsKey("-p") &&
                  params.containsKey("-c") && params.containsKey("-m") &&
                  params.containsKey("-z") &&
                  params.containsKey("-u") && params.containsKey("-x");
      if (b)
      {
         try
         {
            Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            b = false;
         }
      }

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ HashTable.
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      int port = 1414;
      if (args.length > 0 && (args.length % 2) == 0)
      {
         for (int i = 0; i < args.length; i += 2)
         {
            params.put(args[i], args[i + 1]);
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }

      if (allParamsPresent())
      {
         try
         {
            port = Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            port = 1414;
         }
         
         mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
         mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
         mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
         mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
         mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));

         // I don't want to see MQ exceptions at the console.
         MQException.log = null;
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }
   
   /**
    * Handle connecting to the queue manager, issuing PCF command then 
    * disconnect from the queue manager. 
    */
   private void doPCF()
   {
      String qMgrName = (String) params.get("-m");
      String chlName    = (String) params.get("-z");

      MQQueueManager qMgr = null;
      PCFMessageAgent agent = null;
      PCFMessage   request = null;
      
      try
      {
         qMgr = new MQQueueManager(qMgrName, mqht);
         logger("successfully connected to "+ qMgrName);

         agent = new PCFMessageAgent(qMgr);
         logger("successfully created agent");
      
         // https://www.ibm.com/docs/en/ibm-mq/latest?topic=formats-change-copy-create-channel
         
         request = new PCFMessage(MQConstants.MQCMD_CREATE_CHANNEL);

         // Specify the channel name to be created.
         request.addParameter(MQConstants.MQCACH_CHANNEL_NAME, chlName);
         
         // Add parameter to set channel type to be a SVRCONN channel
         request.addParameter(MQConstants.MQIACH_CHANNEL_TYPE, MQConstants.MQCHT_SVRCONN);
         
         // Add parameter to set the max message length to be 10MB
         request.addParameter(MQConstants.MQIACH_MAX_MSG_LENGTH, 10 * 1024 * 1024);
         
         // Add parameter to set the channel security exit name
         request.addParameter(MQConstants.MQCACH_SEC_EXIT_NAME, "C:\\Capitalware\\MQCCI\\mqcci(CCI)");
         
         // Add parameter to set the data parameter for channel security exit
         request.addParameter(MQConstants.MQCACH_SEC_EXIT_USER_DATA, "mqcci.ini");

         agent.send(request);
         
         logger("successfully created channel: " + chlName);
      }
      catch (PCFException pcfe) 
      {
         if (pcfe.reasonCode == MQConstants.MQRCCF_OBJECT_ALREADY_EXISTS) 
            logger("Error: The channel '" + chlName+ "' already exists on the queue manager '" + qMgrName + "'.");
         else
            logger("CC=" +pcfe.completionCode +  " [" + MQConstants.lookupCompCode(pcfe.completionCode) + "] : RC=" + pcfe.reasonCode + " ["+MQConstants.lookupReasonCode(pcfe.reasonCode)+"]");
      }
      catch (MQException e)
      {
         logger("CC=" +e.completionCode +  " [" + MQConstants.lookupCompCode(e.completionCode) + "] : RC=" + e.reasonCode + " ["+MQConstants.lookupReasonCode(e.reasonCode)+"]");
      }
      catch (IOException e)
      {
         logger("IOException:" +e.getLocalizedMessage());
      }
      catch (MQDataException e)
      {
         logger("MQDataException:" +e.getLocalizedMessage());
      }
      catch (Exception e)
      {
         logger("Exception:" +e.getLocalizedMessage());
      }
      finally
      {
         try
         {
            if (agent != null)
            {
               agent.disconnect();
               logger("disconnected from agent");
            }
         }
         catch (MQDataException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }

         try
         {
            if (qMgr != null)
            {
               qMgr.disconnect();
               logger("disconnected from "+ qMgrName);
            }
         }
         catch (MQException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }
      }
   }

   /**
    * A simple logger method
    * @param data
    */
   public static void logger(String data)
   {
      String className = Thread.currentThread().getStackTrace()[2].getClassName();

      // Remove the package info.
      if ( (className != null) && (className.lastIndexOf('.') != -1) )
         className = className.substring(className.lastIndexOf('.')+1);

      System.out.println(LOGGER_TIMESTAMP.format(new Date())+" "+className+": "+Thread.currentThread().getStackTrace()[2].getMethodName()+": "+data);
   }

   public static void main(String[] args)
   {
      MQCreateChannel01 mqcq = new MQCreateChannel01();
      
      try
      {
         mqcq.init(args);
         mqcq.doPCF();
      }
      catch (IllegalArgumentException e)
      {
         logger("Usage: java MQCreateChannel01 -m QueueManagerName -z Channel_Name -h host -p port -c channel -u UserID -x Password");
         System.exit(1);
      }

      System.exit(0);
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

HPE NonStop, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Java, Linux, macOS (Mac OS X), Open Source, PCF, Programming, Raspberry Pi, Unix, Windows, z/OS Comments Off on Java/PCF Program to Create an IBM MQ SVRCONN Channel

WTF GM?!

I have been a GM guy for a long, long time. My first ride was a used 1977 Pontiac Trans Am.

Pontiac Trans Am
In the 90’s, I had a used 4 door 1989 Chevy Cavalier. I used it to go back and forth to work with (great on gas).

Chevy Cavalier
In September 2003, I bought a brand new 2003 Chevy Avalanche. Back in the day, GM used to run “change” ads because of the versatility of the Avalanche. I had it for 11 years and it was a great vehicle. And yes, those are my kids in the bed of the truck that many of you met over the years at various conferences.

Chevy Avalanche
In the Summer of 2014, I decided to trade it in and get a new Chevy Avalanche. I found out that the production of the Chevy Avalanche ended in 2013 and the dealer could not find any new Chevy Avalanches in Ontario (Canada).

So, I looked around at the different trucks/SUVs that were available and decided to get a new 2014 Jeep Wrangler Sahara – Black out edition.

Jeep Wrangler Sahara
Yes, I know it is not a GM product but it was the coolest looking truck I could find.

So now to the point of my story.

Suddenly, I’m see ads for 2024 Chevy Silverado EV. At first, oh that’s cool. But I started to look closer, hey wait a minute, that’s not a Silverado, that’s an Avalanche!!! It even has a similar marketing tag line and VERY similar styling.

Chevy Silverado EV
And the multi-flex midgate:

Chevy Silverado EV

Chevy Silverado EV

Chevy Silverado EV
So, WTF GM?! Why did you call it Chevy Silverado EV?! It should have been called Chevy Avalanche EV!!!!

It really bugs me that the marketing people don’t know the history of the company they work for. Or was it some dumbass executive who thought it would be a great idea and copy Ford with their F150 Lighting naming convention!! Really GM, that is all you got in the tank? Either you don’t know where you come from or you just copy other ICE manufacturers? Sad. Truly sad.

Every Chevy Avalanche owner I ever talked to, loved their Avalanche. So, you clearly missed an opportunity bring them all back home!!! Dumb. Dumb. Dumb.

If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck. Hence, the Chevy Silverado EV looks like an Avalanche, has many features of an Avalanche then you should have called it Chevy Avalanche EV! Right!!

Regards,
Roger Lacroix

General Comments Off on WTF GM?!

Java/PCF Program to Delete an IBM MQ Queue

A couple of days ago, I posted a Java/PCF program that would create a IBM MQ queue. So, if you require creating a queue via Java/PCF then you probably will need to delete a queue via Java/PCF.

If you are used to deleting an IBM MQ queue using runmqsc command then the following simple Java/PCF program will delete a IBM MQ queue based on the following runmqsc command:

DELETE QL('TEST.QUEUE') AUTHREC(YES) PURGE

You can download the source code from here.

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import com.ibm.mq.MQException;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;

/**
 * Program Name
 *  MQDeleteQueue01
 *
 * Description
 *  This java class issues a PCF "delete queue" request message to delete a queue. 
 *  
 *  This PCF code is equivalent to issuing the runmqsc command of:
 *     DELETE QL('TEST.QUEUE') AUTHREC(YES) PURGE
 *
 * Sample Command Line Parameters
 *  -m MQA1 -q Queue_Name -h 127.0.0.1 -p 1414 -c TEST.CHL -u UserID -x Password
 *
 * @author Roger Lacroix
 */
public class MQDeleteQueue01
{
   private static final SimpleDateFormat  LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");

   private Hashtable<String,String> params;
   private Hashtable<String,Object> mqht;

   public MQDeleteQueue01()
   {
      super();
      params = new Hashtable<String,String>();
      mqht = new Hashtable<String,Object>();
   }

   /**
    * Make sure the required parameters are present.
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-h") && params.containsKey("-p") &&
                  params.containsKey("-c") && params.containsKey("-m") &&
                  params.containsKey("-q") &&
                  params.containsKey("-u") && params.containsKey("-x");
      if (b)
      {
         try
         {
            Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            b = false;
         }
      }

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ HashTable.
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      int port = 1414;
      if (args.length > 0 && (args.length % 2) == 0)
      {
         for (int i = 0; i < args.length; i += 2)
         {
            params.put(args[i], args[i + 1]);
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }

      if (allParamsPresent())
      {
         try
         {
            port = Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            port = 1414;
         }
         
         mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
         mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
         mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
         mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
         mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));

         // I don't want to see MQ exceptions at the console.
         MQException.log = null;
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }
   
   /**
    * Handle connecting to the queue manager, issuing PCF command then 
    * disconnect from the queue manager. 
    */
   private void doPCF()
   {
      String qMgrName = (String) params.get("-m");
      String qName    = (String) params.get("-q");

      MQQueueManager qMgr = null;
      PCFMessageAgent agent = null;
      PCFMessage   request = null;
      
      try
      {
         qMgr = new MQQueueManager(qMgrName, mqht);
         logger("successfully connected to "+ qMgrName);

         agent = new PCFMessageAgent(qMgr);
         logger("successfully created agent");
      
         // https://www.ibm.com/docs/en/ibm-mq/latest?topic=formats-mqcmd-delete-q-delete-queue
         
         request = new PCFMessage(MQConstants.MQCMD_DELETE_Q);

         // Specify the queue name to be deleted.
         request.addParameter(MQConstants.MQCA_Q_NAME, qName);

         // Specify that the associated authority record is to be deleted too.  
         // Does not apply to z/OS queue managers.
         request.addParameter(MQConstants.MQIACF_REMOVE_AUTHREC, MQConstants.MQRAR_YES);

         // Specify that the queue is to be deleted even if it contains messages. 
         request.addParameter(MQConstants.MQIACF_PURGE, MQConstants.MQPO_YES);

         agent.send(request);
         
         logger("successfully deleted queue: " + qName);
      }
      catch (PCFException pcfe) 
      {
         if (pcfe.reasonCode == MQConstants.MQRC_UNKNOWN_OBJECT_NAME) 
            logger("Error: The queue '" + qName+ "' does not exists on the queue manager '" + qMgrName + "'.");
         else
            logger("CC=" +pcfe.completionCode +  " [" + MQConstants.lookupCompCode(pcfe.completionCode) + "] : RC=" + pcfe.reasonCode + " ["+MQConstants.lookupReasonCode(pcfe.reasonCode)+"]");
      }
      catch (MQException e)
      {
         logger("CC=" +e.completionCode +  " [" + MQConstants.lookupCompCode(e.completionCode) + "] : RC=" + e.reasonCode + " ["+MQConstants.lookupReasonCode(e.reasonCode)+"]");
      }
      catch (IOException e)
      {
         logger("IOException:" +e.getLocalizedMessage());
      }
      catch (MQDataException e)
      {
         logger("MQDataException:" +e.getLocalizedMessage());
      }
      catch (Exception e)
      {
         logger("Exception:" +e.getLocalizedMessage());
      }
      finally
      {
         try
         {
            if (agent != null)
            {
               agent.disconnect();
               logger("disconnected from agent");
            }
         }
         catch (MQDataException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }

         try
         {
            if (qMgr != null)
            {
               qMgr.disconnect();
               logger("disconnected from "+ qMgrName);
            }
         }
         catch (MQException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }
      }
   }

   /**
    * A simple logger method
    * @param data
    */
   public static void logger(String data)
   {
      String className = Thread.currentThread().getStackTrace()[2].getClassName();

      // Remove the package info.
      if ( (className != null) && (className.lastIndexOf('.') != -1) )
         className = className.substring(className.lastIndexOf('.')+1);

      System.out.println(LOGGER_TIMESTAMP.format(new Date())+" "+className+": "+Thread.currentThread().getStackTrace()[2].getMethodName()+": "+data);
   }

   public static void main(String[] args)
   {
      MQDeleteQueue01 mqcq = new MQDeleteQueue01();
      
      try
      {
         mqcq.init(args);
         mqcq.doPCF();
      }
      catch (IllegalArgumentException e)
      {
         logger("Usage: java MQDeleteQueue01 -m QueueManagerName -q Queue_Name -h host -p port -c channel -u UserID -x Password");
         System.exit(1);
      }

      System.exit(0);
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

HPE NonStop, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Java, Linux, macOS (Mac OS X), Open Source, PCF, Programming, Raspberry Pi, Unix, Windows, z/OS Comments Off on Java/PCF Program to Delete an IBM MQ Queue

Java/PCF Program to Create an IBM MQ Queue

The other day, someone on StackOverflow asked about creating an IBM MQ queue from JMS. I know it is possible to send PCF commands as a JMS message to the Command Server but it seems overly complex when you can simply do it from Java/PCF (non-JMS).

If you are used to creating an IBM MQ queue using runmqsc command then the following simple Java/PCF program will create a IBM MQ queue based on the following runmqsc command:

DEFINE QL('TEST.QUEUE') MAXMSGL(10485760) MAXDEPTH(12345)

You can download the source code from here.

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import com.ibm.mq.MQException;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;

/**
 * Program Name
 *  MQCreateQueue01
 *
 * Description
 *  This java class issues a PCF "create queue" request message to create a local queue 
 *  specifying max message length & max queue depth on a remote queue manager. 
 *  
 *  This PCF code is equivalent to issuing the runmqsc command of:
 *     DEFINE QL('TEST.QUEUE') MAXMSGL(10485760) MAXDEPTH(12345)
 *
 * Sample Command Line Parameters
 *  -m MQA1 -q Queue_Name -h 127.0.0.1 -p 1414 -c TEST.CHL -u UserID -x Password
 *
 * @author Roger Lacroix
 */
public class MQCreateQueue01
{
   private static final SimpleDateFormat  LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");

   private Hashtable<String,String> params;
   private Hashtable<String,Object> mqht;

   public MQCreateQueue01()
   {
      super();
      params = new Hashtable<String,String>();
      mqht = new Hashtable<String,Object>();
   }

   /**
    * Make sure the required parameters are present.
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-h") && params.containsKey("-p") &&
                  params.containsKey("-c") && params.containsKey("-m") &&
                  params.containsKey("-q") &&
                  params.containsKey("-u") && params.containsKey("-x");
      if (b)
      {
         try
         {
            Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            b = false;
         }
      }

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ HashTable.
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      int port = 1414;
      if (args.length > 0 && (args.length % 2) == 0)
      {
         for (int i = 0; i < args.length; i += 2)
         {
            params.put(args[i], args[i + 1]);
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }

      if (allParamsPresent())
      {
         try
         {
            port = Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            port = 1414;
         }
         
         mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
         mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
         mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
         mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
         mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));

         // I don't want to see MQ exceptions at the console.
         MQException.log = null;
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }
   
   /**
    * Handle connecting to the queue manager, issuing PCF command then 
    * disconnect from the queue manager. 
    */
   private void doPCF()
   {
      String qMgrName = (String) params.get("-m");
      String qName    = (String) params.get("-q");

      MQQueueManager qMgr = null;
      PCFMessageAgent agent = null;
      PCFMessage   request = null;
      
      try
      {
         qMgr = new MQQueueManager(qMgrName, mqht);
         logger("successfully connected to "+ qMgrName);

         agent = new PCFMessageAgent(qMgr);
         logger("successfully created agent");
      
         // https://www.ibm.com/docs/en/ibm-mq/latest?topic=formats-change-copy-create-queue
         
         request = new PCFMessage(MQConstants.MQCMD_CREATE_Q);

         // Specify the queue name to be created.
         request.addParameter(MQConstants.MQCA_Q_NAME, qName);
         
         // Add parameter to set queue type to be a local queue
         request.addParameter(MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL);
         
         // Add parameter to set the max message length to be 10MB
         request.addParameter(MQConstants.MQIA_MAX_MSG_LENGTH, 10 * 1024 * 1024);
         
         // Add parameter to set the max queue depth to be 12,345
         request.addParameter(MQConstants.MQIA_MAX_Q_DEPTH, 12345);

         agent.send(request);
         
         logger("successfully created queue: " + qName);
      }
      catch (PCFException pcfe) 
      {
         if (pcfe.reasonCode == MQConstants.MQRCCF_OBJECT_ALREADY_EXISTS) 
            logger("Error: The queue '" + qName+ "' already exists on the queue manager '" + qMgrName + "'.");
         else
            logger("CC=" +pcfe.completionCode +  " [" + MQConstants.lookupCompCode(pcfe.completionCode) + "] : RC=" + pcfe.reasonCode + " ["+MQConstants.lookupReasonCode(pcfe.reasonCode)+"]");
      }
      catch (MQException e)
      {
         logger("CC=" +e.completionCode +  " [" + MQConstants.lookupCompCode(e.completionCode) + "] : RC=" + e.reasonCode + " ["+MQConstants.lookupReasonCode(e.reasonCode)+"]");
      }
      catch (IOException e)
      {
         logger("IOException:" +e.getLocalizedMessage());
      }
      catch (MQDataException e)
      {
         logger("MQDataException:" +e.getLocalizedMessage());
      }
      catch (Exception e)
      {
         logger("Exception:" +e.getLocalizedMessage());
      }
      finally
      {
         try
         {
            if (agent != null)
            {
               agent.disconnect();
               logger("disconnected from agent");
            }
         }
         catch (MQDataException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }

         try
         {
            if (qMgr != null)
            {
               qMgr.disconnect();
               logger("disconnected from "+ qMgrName);
            }
         }
         catch (MQException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }
      }
   }

   /**
    * A simple logger method
    * @param data
    */
   public static void logger(String data)
   {
      String className = Thread.currentThread().getStackTrace()[2].getClassName();

      // Remove the package info.
      if ( (className != null) && (className.lastIndexOf('.') != -1) )
         className = className.substring(className.lastIndexOf('.')+1);

      System.out.println(LOGGER_TIMESTAMP.format(new Date())+" "+className+": "+Thread.currentThread().getStackTrace()[2].getMethodName()+": "+data);
   }

   public static void main(String[] args)
   {
      MQCreateQueue01 mqcq = new MQCreateQueue01();
      
      try
      {
         mqcq.init(args);
         mqcq.doPCF();
      }
      catch (IllegalArgumentException e)
      {
         logger("Usage: java MQCreateQueue01 -m QueueManagerName -q Queue_Name -h host -p port -c channel -u UserID -x Password");
         System.exit(1);
      }

      System.exit(0);
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

HPE NonStop, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Java, Linux, macOS (Mac OS X), Open Source, PCF, Programming, Raspberry Pi, Unix, Windows Comments Off on Java/PCF Program to Create an IBM MQ Queue

IBM MQ Fix Pack 9.0.0.13 Released

IBM has just released Fix Pack 9.0.0.13 for IBM MQ V9.0 LTS
https://www.ibm.com/support/pages/downloading-ibm-mq-90013

Regards,
Roger Lacroix
Capitalware Inc.

Fix Packs for MQ, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Linux, Unix, Windows Comments Off on IBM MQ Fix Pack 9.0.0.13 Released

OpenBSD v7.1 Released

Theo de Raadt has just released OpenBSD v7.1.
https://www.openbsd.org/71.html

The OpenBSD project produces a FREE, multi-platform 4.4BSD-based UNIX-like operating system. Our efforts emphasize portability, standardization, correctness, proactive security and integrated cryptography.

Regards,
Roger Lacroix
Capitalware Inc.

Open Source, Operating Systems Comments Off on OpenBSD v7.1 Released

IBM has announced IBM MQ 9.3

IBM has just announced IBM MQ 9.3 for multi-platforms and IBM MQ on Cloud:
https://www.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/8/877/ENUSZP22-0148/index.html

Or in a PDF file:
https://www.ibm.com/downloads/cas/EM-ENUSZP22-0148-CA/name/EM-ENUSZP22-0148-CA.PDF

IBM MQ 9.3 will be available for electronic download on June, 23, 2022.

Note: Under “Statement of general direction” it says: IBM intends to make IBM MQ for z/OS®, 9.3 and IBM MQ Appliance 9.3 firmware available in the future.

Regards,
Roger Lacroix
Capitalware Inc.

IBM i (OS/400), IBM MQ, IBM MQ Appliance, Linux, Unix, Windows, z/OS Comments Off on IBM has announced IBM MQ 9.3

Undocumented FastTransferOrder Parameter

T.Rob Wyatt was looking for information on the undocumented parameter called FastTransferOrder on the MQ ListServer. The original link to the information was broken. Angel Rivera of IBM has posted a new link with the relevent information here.

I’m going to post the contents of the new link here, just in case the IBM link becomes broken again.

Here is Morag Hughson’s response to a question posted on IBM Support Form about getter applications receiving an equal number of messages:

The default behaviour of the queue manager is to deliver messages to MQGET-waiters in a LIFO manner. It is more efficient for MQ to keep one thread/process ‘hot’ than to maximise context switching and deliver equal numbers of messages across the waiters.

In a real world set up it is not generally necessary to change this as work gets processed in the most efficient way and MQGET-waiters come and go and messages arrive on the queue in an unpredictable schedule. It is often seen when users are testing on a small scale and can see that the distribution is not round robin as they expected it would be.

If it truly is required to give up efficiency in order to have a more even distribution then it can be changed using the FastTransferOrder tuning parameter.

IBM’s Answer:

1) Even message distribution when getting messages
If multiple applications get messages from the same queue, then the messages will be evenly distributed between the get applications, if FIFO message delivery is enabled on the queue manager.
Procedure:
* Add the following tuning parameter to the queue manager’s qm.ini file:

TuningParameters:
   FastTransferOrder=FIFO

* Restart the queue manager

Possible values are: FastTransferOrder=[FIFO|LIFO]
Note that the default order is: LIFO
Where:
FIFO = First In First Out
LIFO = Last In First Out

2) APAR IZ85974 – Implement the FastTransferOrder property.
IZ85974: IN WMQ V7.0 FASTTRANSFERORDER PARAMETER IS NOT WORKING AS EXPECTED WHEN ASYNCHRONOUS CONSUME IS BEING USED.
Fixed in: MQ Fix Pack 7.0.1.5 (queue manager)

The FastTransferOrder tuning parameter allows the queue manager to deliver messages in a more round-robin manner by servicing waiting MQGETs in FIFO order rather than the default LIFO order.

Add the following tuning parameter to the queue manager’s qm.ini file:

TuningParameters:
   FastTransferOrder=FIFO

Restart the queue manager.

Note: The FastTransferOrder parameter is used to define which getter application will receive the next incoming message and NOT how the order of messages will be handled.

Regards,
Roger Lacroix
Capitalware Inc.

IBM i (OS/400), IBM MQ, IBM MQ Appliance, Linux, Raspberry Pi, Unix, Windows Comments Off on Undocumented FastTransferOrder Parameter

My Bad – Accessibility Features Were Missing

I did an oops and I’m not sure when. I’ve always want to treat all people the same way, that is why I make sure Capitalware products support as many languages as possible and support people with reading issues.

Capitalware uses Excelsior Jet to compile and link Java applications into a stand-alone executable and on Windows, I use Inno Setup to package and create a Windows installer program.

In Excelsior Jet, one of the options I selected was “Java Accessibility”, hence, the necessary DLL (on Windows) would be included in the build. Somehow in Inno Setup, when I recursively included the build, the DLL was missed. I don’t know how but it is weird.

So, I have gone through the Inno Setup process for each program and made sure that the missing DLL is included. I have re-packaged the following Capitalware programs:

If you previously tried out one of the above programs and the display didn’t look right or didn’t work at all, I’m very sorry. Please download the latest build of the product again as they have all been rebuild with the correct DLLs.

Note: This problem is only on Windows.

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, MQ Batch Toolkit, MQ Visual Browse, MQ Visual Edit, MQTT Message Editing Suite Comments Off on My Bad – Accessibility Features Were Missing

IBM MQ Fix Pack 9.1.0.11 Released

IBM has just released Fix Pack 9.1.0.11 for IBM MQ V9.1 LTS:
https://www.ibm.com/support/pages/downloading-ibm-mq-91011

Regards,
Roger Lacroix
Capitalware Inc.

Fix Packs for MQ, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Linux, Unix, Windows Comments Off on IBM MQ Fix Pack 9.1.0.11 Released