JMS应用程序无法读取由PL1应用程序创建的MQ消息

时间:2018-12-03 10:23:54

标签: java jms ibm-mq

我对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格式的消息属性时才有效。否则,枚举为空。

1 个答案:

答案 0 :(得分:0)

  

PL1应用程序正在通过MQHRF2设置消息属性。一世   假设这就是造成问题的原因。

MQRFH2结构相当复杂,不是很简单。我猜测创建PL / 1程序的人没有正确创建MQRFH2结构,因此,您的Java / JMS应用程序将无法识别它。

告诉您的PL / 1程序员去从https://capitalware.com/mq_code_c.html下载 Jsmqput C程序。它显示了如何正确创建MQRFH2结构。需要注意的大事项是,所有文件夹都必须与4字节的边界对齐(填充空白)。