如何解决无法将消息放入回复队列的问题。 MQRC=2110?

问题描述 投票:0回答:1

我在通过以下方式发送消息时遇到问题。我正在通过 JMS 使用 CICS 发送消息。我在主机端收到错误“无法将消息放入回复队列”,错误代码为 MQRC=2110,并且还收到空响应。你能帮我解决这个问题吗?

我正在发送这样的代码...

Hashtable<String, String> environment = new Hashtable<String, String>();

            environment.put(Context.INITIAL_CONTEXT_FACTORY,
                    "com.ibm.websphere.naming.WsnInitialContextFactory");

            // Setup JNDI context
            Context context = new InitialContext(environment);

            // Look up connection factory and destination queue
            ConnectionFactory connectionFactory = (ConnectionFactory) context
                    .lookup("jms/xyz");
            
            // creating request Queue
            Destination requestQueue = (Destination) context
                    .lookup(requestQueueName);

            Connection connection = connectionFactory.createConnection();
            Session session = connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            logger.info("getJMSConnection:: JMS connections  created ...");
            connection.start();
    
            ((JmsDestination) requestQueue).setIntProperty(
                    MQConstants.WMQ_MQMD_MESSAGE_CONTEXT,
                    MQConstants.WMQ_MDCTX_SET_IDENTITY_CONTEXT);
            
            logger.info("doCicsRequestReply: Request  queue created  ");
            // creating response queue
            Destination replyQueue = (Destination) context
                    .lookup(replyToQueueName);
            ((JmsDestination) replyQueue).setBooleanProperty(MQConstants.WMQ_MQMD_WRITE_ENABLED, true);

            
            // Create connection, session, and producer
            MessageProducer producer = session.createProducer(requestQueue);
            logger.info("doCicsRequestReply: Request and response queue created  ");
            
            // Setting up request headers and message
        
    
        
            BytesMessage message = session.createBytesMessage();
            // Request Headers
             message.setJMSMessageID(MQConstants.MQMI_NONE.toString());
             message.setJMSCorrelationIDAsBytes(MQConstants.MQCI_NEW_SESSION);
            message.setStringProperty("JMS_IBM_MQMD_UserIdentifier", racfUserid);
            message.setIntProperty("JMS_IBM_MQMD_CodedCharSetId",CHARSET_IBM500);
            message.setStringProperty("JMS_IBM_MQMD_Format", MQConstants.MQFMT_CICS);
            message.setJMSReplyTo(replyQueue);
            message.setIntProperty("JMS_IBM_MQMD_Encoding", messageEncoding);
            message.setIntProperty("JMS_IBM_MQMD_Persistence", persistence);
            
            logger.info("doCicsRequestReply: Request header setup completed.. ");

            byte blanks[] = new byte[8];
            for (int i = 0; i < blanks.length; i++)
                blanks[i] = (byte) ' ';

            // Construct the CIH header as a byte array
            ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
            DataOutputStream outData = new DataOutputStream(outBytes);
        
            outData.writeBytes("CIH ");      // MQCHAR strucId
            outData.writeInt(2);            // MQLONG version
            outData.writeInt(180);          // MQLONG strucLength
            logger.info("messageEncoding .. "+messageEncoding);
            outData.writeInt(messageEncoding); // MQLONG encoding
            outData.writeInt(CHARSET_IBM500); // MQLONG CodedCharSetId;
            outData.writeBytes(MQConstants.MQFMT_STRING); // MQCHAR8 Format;
            outData.writeInt(4);             // MQLONG Flags;
            outData.writeInt(0);            // MQLONG ReturnCode;
            outData.writeInt(0);            // MQLONG CompCode; Completion code 
            outData.writeInt(0);            // MQLONG Reason; MQ reason code 
            outData.writeInt(0x111);            // MQCUOWC_ONLY // MQLONG UOWControl; Unit of work control
        
            outData.writeInt(-2); // MQCGWI_DEFAULT // MQLONG GetWaitInterval;
            outData.writeInt(1); // MQCLT_PROGRAM // MQLONG LinkType;
            outData.writeInt(-1); // MQLONG OutputDataLength;
            outData.writeInt(0); // MQLONG FacilityKeepTime;
            outData.writeInt(0); // MQLONG ADSDescriptor;
            outData.writeInt(0); // MQLONG ConversationalTask;
            outData.writeInt(0); // MQLONG TaskEndStatus;
            outData.write(blanks, 0, 8); // MQBYTE Facility[8];
            outData.writeBytes(BLANK4); // MQCHAR4 Function;
            outData.writeBytes(BLANK4); // MQCHAR4 `    ;
            outData.writeBytes(BLANK8); // MQCHAR8 Authenticator;
            outData.writeBytes(BLANK8); // MQCHAR8 Reserved1;
            outData.writeBytes(MQConstants.MQFMT_STRING); // MQCHAR8
                                                            // ReplyToFormat;
            outData.writeBytes(BLANK4); // MQCHAR4 RemoteSysId;
            outData.writeBytes(BLANK4); // MQCHAR4 RemoteTrans Id;
            outData.writeBytes(cicsTxnCode); // MQCHAR4 TransactionId;;
            outData.writeBytes(BLANK4); // MQCHAR4 FacilityLike;
            outData.writeBytes(BLANK4); // MQCHAR4 AttentionId;
            outData.writeBytes(BLANK4); // MQCHAR4 StartCode;
            outData.writeBytes(BLANK4); // MQCHAR4 CancelCode;
            outData.writeBytes(BLANK4); // MQCHAR4 NextTransactionId;
            outData.writeBytes(BLANK8); // MQCHAR8 Reserved2;
            outData.writeBytes(BLANK8); // MQCHAR8 Reserved3;
            outData.writeInt(0); // MQLONG CursorPosition;
            outData.writeInt(0); // MQLONG ErrorOffset;
            outData.writeInt(0); // MQLONG InputItem;
            outData.writeInt(0); // MQLONG Reserved4;
            logger.info("doCicsRequestReply: Setting message body..");
            // ---- make sure progName is exactly 8 characters
            StringBuffer pgmName = new StringBuffer(progName);
            for (int i = pgmName.length(); i < 8; i++)
                pgmName.append(' ');
            // ---- write program name followed by commarea
            outData.writeBytes(pgmName.substring(0, 8)); 
            outData.writeBytes(commArea);
java jms websphere ibm-mq cics
1个回答
0
投票

您没有遵循我在同一主题的另一篇文章中给您的任何提示。你的代码有很多错误,所以我决定尝试一下我自己的代码,因为我今天很无聊。

我认为您没有理解 MQ 如何处理嵌入式结构的链接:

这设置了 MQMD 标头的 CCSID:

message.setIntProperty("JMS_IBM_MQMD_CodedCharSetId",819);

这设置了第一个嵌入结构的 CCSID:

message.setIntProperty("JMS_IBM_Character_Set", 819);

接下来,为什么要设置 MQMD UserId 字段?真的没有什么目的。

并且您的 MQMD 格式字段设置不正确。

最后,消息有效负载或任何结构是否将采用 EBCDIC?如果没有,请不要尝试设置 CCSID,因为它只会中断或生成错误。

这是一个功能齐全的 JMS 应用程序,它将 CICS 消息放入队列。

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

import javax.jms.BytesMessage;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.ibm.msg.client.jms.JmsDestination;

import com.ibm.mq.MQException;
import com.ibm.mq.constants.MQConstants;

/**
 * Program Name
 *  MQTestJMS03
 *
 * Description
 *  This java JMS class will connect to a remote queue manager using JNDI and put a message to a queue.
 *
 * Sample Command Line Parameters
 *  -c myQCF -q dev.test.q -f C:\JNDI-Directory\roger\mqjndi -u UserID -x Password
 *
 *  Sample MQ JNDI Commands:
 *    DEFINE QCF(myQCF) QMANAGER(MQA1) CHANNEL(TEST.CHL) HOSTNAME(127.0.0.1) PORT(1414) TRANSPORT(CLIENT) FAILIFQUIESCE(YES)
 *    DEFINE Q(dev.test.q) QUEUE(TEST.Q1) QMANAGER(MQA1) TARGCLIENT(JMS) FAILIFQUIESCE(YES)
 *    DEFINE Q(dev.test.q.reply) QUEUE(TEST.REPLY.Q) QMANAGER(MQA1) TARGCLIENT(JMS) FAILIFQUIESCE(YES)
 *
 * @author Roger Lacroix
 */
public class MQTestJMS03
{
   private static final SimpleDateFormat  LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
   private final String BLANK4 = "    ";
   private final String BLANK8 = "        ";

   private QueueConnectionFactory cf;
   private String qName;
   private Destination destination = null;
   private Queue replyQ;
   private Hashtable<String,String> params;

   public MQTestJMS03() throws NamingException
   {
      super();
      params = new Hashtable<String,String>();
   }

   /**
    * Make sure the required parameters are present.
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-c") && params.containsKey("-q") &&
                  params.containsKey("-f") &&
                  params.containsKey("-u") && params.containsKey("-x");

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ variables.
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      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())
      {
         Hashtable<String,String> env = new Hashtable<String,String>();
         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
         env.put(Context.PROVIDER_URL, "file:/"+(String) params.get("-f"));

         try
         {
            Context ctx = new InitialContext(env);

            cf = (QueueConnectionFactory) ctx.lookup((String) params.get("-c"));
            qName = ((Queue) ctx.lookup((String) params.get("-q"))).getQueueName();
            replyQ = (Queue) ctx.lookup((String) params.get("-q") + ".reply");
         }
         catch (NamingException e)
         {
            MQTestJMS03.logger(e.getLocalizedMessage());
            e.printStackTrace();
            throw new IllegalArgumentException();
         }
         catch (JMSException e)
         {
            MQTestJMS03.logger(e.getLocalizedMessage());
            e.printStackTrace();
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }

   /**
    * Test the connection to the queue manager.
    * @throws MQException
    */
   private void testConn() throws JMSException
   {
      QueueConnection conn = null;
      QueueSession session = null;

      try
      {
         conn = cf.createQueueConnection((String) params.get("-u"), (String) params.get("-x"));
         conn.start();

         session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
         MQTestJMS03.logger("successfully connected.");

         sendMsg(session);
      }
      catch (JMSException e)
      {
         MQTestJMS03.logger("getLinkedException()=" + e.getLinkedException());
         MQTestJMS03.logger(e.getLocalizedMessage());
         e.printStackTrace();
      }
      finally
      {
         try
         {
            if (session != null)
               session.close();
         }
         catch (Exception ex)
         {
            MQTestJMS03.logger("session.close() : " + ex.getLocalizedMessage());
         }

         try
         {
            if (conn != null)
               conn.stop();
         }
         catch (Exception ex)
         {
            MQTestJMS03.logger("connection.stop() : " + ex.getLocalizedMessage());
         }

         try
         {
            if (conn != null)
               conn.close();
         }
         catch (Exception ex)
         {
            MQTestJMS03.logger("connection.close() : " + ex.getLocalizedMessage());
         }
      }
   }

   /**
    * Send a message to a queue.
    * @throws MQException
    */
   private void sendMsg(QueueSession session) throws JMSException
   {
      QueueSender sender = null;

      try
      {
         destination = session.createQueue(qName);

         ((JmsDestination) destination).setIntProperty(MQConstants.WMQ_MQMD_MESSAGE_CONTEXT,MQConstants.WMQ_MDCTX_SET_IDENTITY_CONTEXT);

         // Enable write of MQMD fields. See documentation for further details.
         ((JmsDestination) destination).setBooleanProperty(MQConstants.WMQ_MQMD_WRITE_ENABLED, true);

         sender = session.createSender((Queue) destination);

         BytesMessage message = session.createBytesMessage();

         // Request Headers
         message.setStringProperty("JMS_IBM_MQMD_UserIdentifier", "RECFUSER");
//         message.setIntProperty("JMS_IBM_MQMD_CodedCharSetId",819);
         message.setJMSReplyTo(replyQ);

         /* Set the format value in the MQRFH2 header to CICS because that is the next embedded message. */
         message.setStringProperty("JMS_IBM_Format", "MQCICS");
//         message.setIntProperty("JMS_IBM_Character_Set", 819);

         // Construct the CIH header as a byte array
         ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
         DataOutputStream outData = new DataOutputStream(outBytes);

         outData.writeBytes("CIH ");     // MQCHAR strucId
         outData.writeInt(2);            // MQLONG version
         outData.writeInt(180);          // MQLONG strucLength
         outData.writeInt(MQConstants.MQENC_INTEGER_NORMAL); // MQLONG encoding

         // Only set this to 500 if your comm area aka message data is EBCDIC
         outData.writeInt(500);          // MQLONG CodedCharSetId;
         outData.writeBytes(MQConstants.MQFMT_STRING); // MQCHAR8 Format;
         outData.writeInt(4);            // MQLONG Flags;
         outData.writeInt(0);            // MQLONG ReturnCode;
         outData.writeInt(0);            // MQLONG CompCode; Completion code
         outData.writeInt(0);            // MQLONG Reason; MQ reason code
         outData.writeInt(0x111);        // MQCUOWC_ONLY // MQLONG UOWControl; Unit of work control

         outData.writeInt(-2);       // MQCGWI_DEFAULT // MQLONG GetWaitInterval;
         outData.writeInt(1);        // MQCLT_PROGRAM // MQLONG LinkType;
         outData.writeInt(-1);       // MQLONG OutputDataLength;
         outData.writeInt(0);        // MQLONG FacilityKeepTime;
         outData.writeInt(0);        // MQLONG ADSDescriptor;
         outData.writeInt(0);        // MQLONG ConversationalTask;
         outData.writeInt(0);        // MQLONG TaskEndStatus;
         outData.write(BLANK8.getBytes()); // MQBYTE Facility[8];
         outData.writeBytes(BLANK4); // MQCHAR4 Function;
         outData.writeBytes(BLANK4); // MQCHAR4 `    ;
         outData.writeBytes(BLANK8); // MQCHAR8 Authenticator;
         outData.writeBytes(BLANK8); // MQCHAR8 Reserved1;
         outData.writeBytes(MQConstants.MQFMT_STRING); // MQCHAR8
         outData.writeBytes(BLANK4); // MQCHAR4 RemoteSysId;
         outData.writeBytes(BLANK4); // MQCHAR4 RemoteTrans Id;
         outData.writeBytes("ABCD"); // MQCHAR4 TransactionId;;
         outData.writeBytes(BLANK4); // MQCHAR4 FacilityLike;
         outData.writeBytes(BLANK4); // MQCHAR4 AttentionId;
         outData.writeBytes(BLANK4); // MQCHAR4 StartCode;
         outData.writeBytes(BLANK4); // MQCHAR4 CancelCode;
         outData.writeBytes(BLANK4); // MQCHAR4 NextTransactionId;
         outData.writeBytes(BLANK8); // MQCHAR8 Reserved2;
         outData.writeBytes(BLANK8); // MQCHAR8 Reserved3;
         outData.writeInt(0);        // MQLONG CursorPosition;
         outData.writeInt(0);        // MQLONG ErrorOffset;
         outData.writeInt(0);        // MQLONG InputItem;
         outData.writeInt(0);        // MQLONG Reserved4;
         // ---- make sure progName is exactly 8 characters
         StringBuffer pgmName = new StringBuffer("TESTPGM");
         for (int i = pgmName.length(); i < 8; i++)
             pgmName.append(' ');
         // ---- write program name followed by commarea
         outData.writeBytes(pgmName.substring(0, 8));
         outData.writeBytes("commArea 012356789");

         message.writeBytes(outBytes.toByteArray());

         sender.send(message);

         MQTestJMS03.logger("Message sent.");
      }
      catch (JMSException e)
      {
         MQTestJMS03.logger("getLinkedException()=" + e.getLinkedException());
         MQTestJMS03.logger(e.getLocalizedMessage());
         e.printStackTrace();
      }
      catch (IOException e)
      {
         MQTestJMS03.logger(e.getLocalizedMessage());
         e.printStackTrace();
      }
      finally
      {
         try
         {
            if (sender != null)
               sender.close();
         }
         catch (Exception ex)
         {
            MQTestJMS03.logger("sender.close() : " + ex.getLocalizedMessage());
         }
      }
   }

   /**
    * 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);
   }

   /**
    * main line
    * @param args
    */
   public static void main(String[] args)
   {
      try
      {
         MQTestJMS03 tj = new MQTestJMS03();
         tj.init(args);
         tj.testConn();
         MQTestJMS03.logger("finished.");
      }
      catch (IllegalArgumentException e)
      {
         MQTestJMS03.logger("Usage: java MQTestJMS03 -c QueueConnectionFactoryName -q JMS_Queue_Name -f path_to_MQ_JNDI -u UserID -x Password");
         System.exit(1);
      }
      catch (NamingException ex)
      {
         MQTestJMS03.logger(ex.getLocalizedMessage());
         ex.printStackTrace();

      }
      catch (JMSException e)
      {
         MQTestJMS03.logger("getLinkedException()=" + e.getLinkedException());
         MQTestJMS03.logger(e.getLocalizedMessage());
         e.printStackTrace();
      }
      catch (Exception ex)
      {
         MQTestJMS03.logger(ex.getLocalizedMessage());
         ex.printStackTrace();
      }
   }
}

这是从我的代码发送的消息的十六进制转储,显示了 2 个嵌入结构:

消息的 MQMD 格式字段如下所示:

此处显示了 MQRFH2 标头、JMS 属性和正确设置的 CICS 格式:

现在,我目前没有 CICS 区域来测试您的实际格式化 CICS 标头和消息负载。但如果不正确,只需参考 cmqc.h 文件中的 MQCIH 结构即可。

或者您可以只使用 MQ Java 基类中的 MQCIH 类。

© www.soinside.com 2019 - 2024. All rights reserved.