我对Websphere MQ和JMS有一个奇怪的问题。 有一个PL1应用程序将消息放入队列,这些消息由我的Java应用程序读取(在tomcat中运行)。 问题在于,一旦PL1应用程序将消息放入队列中,Java应用程序就无法再从该队列中读取任何内容-就像队列中没有任何消息一样。 另一方面,MQ浏览器显示消息确实存在。队列管理员还告诉我,在我尝试提取消息时,他看不到队列中的任何错误。
我尝试使用侦听器和定制类通过JMS QueueBrowser读取Java tomcat应用程序中的消息。两种方法都不行。例如,对于QueueBrowser,我什至在调用QueueBrowser.getEnumeration方法时也没有异常。
有趣的是,当再次清空队列,并且本地Java测试应用程序(而非PL1应用程序)将消息放入队列时,它们可以被Java tomcat应用程序读取。 一旦PL1应用程序再次添加了一条消息,对于Java tomat应用程序,所有的消息都不再可见=>甚至是那些由本地Java测试应用程序添加并且以前可以使用的消息。
要说的一件事很重要:PL1应用程序正在通过MQSETMP在消息句柄上设置消息属性:
Use the MQSETMP call to set or modify a property of a message handle.
Syntax
MQSETMP (Hconn, Hmsg, SetPropOpts, Name, PropDesc, Type, ValueLength, Value, Compcode, Reason)
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_8.0.0/com.ibm.mq.ref.dev.doc/q101910_.htm)。
我认为这就是问题的原因。 如果队列的设置“ PROPCTL”设置为“ NONE”(而不是“ COMPAT”),则Java应用程序可以从PL1读取消息,但是消息属性不可见。 我们想使用这些消息属性,尽管这就是为什么这不是我们的选择。我们还尝试了PROPCTL的其他可能选项,但这些选项也不起作用。
有什么我可以从Java客户端做的事情吗?我可以尝试一下Java的Websphere MQ类的任何可能设置吗?
Websphere MQ版本: 8
Java版(com.ibm.mq.allclient)的Websphere MQ类: 9.0.4.0
修改
这是java客户端通过QueueBrowser获取消息的最小示例:
package jmsminimal;
import java.util.Date;
import java.util.Enumeration;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.ibm.mq.jms.JMSC;
import com.ibm.mq.jms.MQQueueConnectionFactory;
public class JMSTest {
public static void main(String[] args) throws JMSException {
String hostname = "hostname";
String channel = "channelname";
int port = 1414;
String queueMgr = "queuemgrname";
String queueName = "queuename";
String username = "username";
String password = "";
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(hostname);
mqQueueConnectionFactory.setChannel(channel);
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setQueueManager(queueMgr);
mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
Connection connection = mqQueueConnectionFactory.createConnection(username, password);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(queueName);
QueueBrowser browser = session.createBrowser(queue);
connection.start();
Enumeration entriesEnum = browser.getEnumeration();
while (entriesEnum.hasMoreElements()) {
Message message = (Message) entriesEnum.nextElement();
TextMessage textMessage = (TextMessage) message;
System.out.println("*********************************************************");
System.out.println("JMSMessageID: " + textMessage.getJMSMessageID());
System.out.println("JMSCorrelationID: " + textMessage.getJMSCorrelationID());
System.out.println("JMSTimestamp: " + new Date(textMessage.getJMSTimestamp()).toString());
System.out.println("\nProperties:");
Enumeration propertiesEnum = textMessage.getPropertyNames();
while (propertiesEnum.hasMoreElements()) {
String propertyKey = (String) propertiesEnum.nextElement();
String propertyValue = textMessage.getObjectProperty(propertyKey).toString();
System.out.println(propertyKey + "=" + propertyValue);
}
System.out.println("\nText: \n" + textMessage.getText());
System.out.println("*********************************************************\n");
}
connection.close();
session.close();
}
}
以下是pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.jms</groupId>
<artifactId>jmsminimal</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.0.4.0</version>
</dependency>
</dependencies>
</project>
如前所述-该示例仅在队列中没有PL1发送的消息并且包含MQHRF2格式的消息属性时才有效。否则,枚举为空。
答案 0 :(得分:0)
PL1应用程序正在通过MQHRF2设置消息属性。一世 假设这就是造成问题的原因。
MQRFH2结构相当复杂,不是很简单。我猜测创建PL / 1程序的人没有正确创建MQRFH2结构,因此,您的Java / JMS应用程序将无法识别它。
告诉您的PL / 1程序员去从https://capitalware.com/mq_code_c.html下载 Jsmqput C程序。它显示了如何正确创建MQRFH2结构。需要注意的大事项是,所有文件夹都必须与4字节的边界对齐(填充空白)。