我在通过以下方式发送消息时遇到问题。我正在通过 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);
您没有遵循我在同一主题的另一篇文章中给您的任何提示。你的代码有很多错误,所以我决定尝试一下我自己的代码,因为我今天很无聊。
我认为您没有理解 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 类。