Spring JMS + IBM MQ: How to set message buffer siz

2019-08-13 03:14发布

I'm unable to process large messages from IBM MQ and get the below error:

JMSCMQ0001: WebSphere MQ call failed with compcode '1' ('MQCC_WARNING') reason '2080' ('MQRC_TRUNCATED_MSG_FAILED')

I'm using the DefaultListenerContainer and not consuming via a MessageConsumer using IBM MQ Java API classes directly. I believe by using IBM MQ JMS API you can specific options before retrieving the message from the queue. But how do I do that with DefaultListenerContainer, is there a system property I can set for these?

If using IBM MQ JMS API(I'm not consuming message like this, pasted just for reference):

MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions(); mqGetMessageOptions.waitInterval = ipreoProperties.getMqReceiveWaitTime(); mqGetMessageOptions.options = MQC.MQGMO_WAIT | MQC.MQPMO_SYNCPOINT | MQC.MQGMO_ACCEPT_TRUNCATED_MSG;

Below is my Java Config for the IBM MQ Connection:

@Bean
    public CachingConnectionFactory ipreoMQCachingConnectionFactory() {

        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();

        //Not defining MQQueueConnectionFactory as separate bean as Spring boot's auto-configuration finds two instances
        //of ConnectionFactory and throws ambiguous implementation exception 
        //One implementation is CachingConnectionFactory and other one would be MQQueueConnectionFactory if defined separately

        MQQueueConnectionFactory mqConnectionFactory = new MQQueueConnectionFactory();

        try {

            mqConnectionFactory.setHostName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_HOSTNAME));
            mqConnectionFactory.setQueueManager(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_QUEUE_MGR));
            mqConnectionFactory.setPort(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_PORT, Integer.class));
            mqConnectionFactory.setChannel(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_CHANNEL));
            //mqConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);

            //Setting connection mode as Client so it doesn't complain for native IBM MQ libraries
            mqConnectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);

        } catch (JMSException exception) {
            exception.printStackTrace();
        }

        cachingConnectionFactory.setTargetConnectionFactory(mqConnectionFactory);

        //Setting session caching size as 10, don't think we need more
        cachingConnectionFactory.setSessionCacheSize(10);
        cachingConnectionFactory.setReconnectOnException(true);

        return cachingConnectionFactory;
    }

 public DefaultMessageListenerContainer ipreoDealActivityListenerContainer() {

        DefaultMessageListenerContainer factory = new DefaultMessageListenerContainer();
        factory.setConnectionFactory(ipreoMQCachingConnectionFactory());
        factory.setDestinationName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_DEAL_QUEUE_NAME));
        factory.setMessageListener(ipreoDealActivityListener());
        factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);

        return factory;
    }

@Bean
    public MessageListener ipreoDealActivityListener() {
        return new IpreoDealActivityListener();
    }

Appreciate your help, thanks.

2条回答
Juvenile、少年°
2楼-- · 2019-08-13 03:28

On a client connection to a queue manager you can limit the size of messages on both the server and client side. I've seen this error before when the client side limit was smaller then the size of the message.

I don't know how you can set the message size limit directly in the JMS client, but you could use a Client Channel Definition Table. It's a file containing the details for connecting to queue managers, created on a queue manager and then copied to the client host. You need to reference the file by issuing setCCDTURL on the connection factory (setting the host, port and channel is not required when using a CCDT, the CCDT will specify those).

When the CCDT is created on the queue manager the appropriate message size limit needs to be set on the client channel.

The server side limit is set on the server connection channel.

查看更多
我想做一个坏孩纸
3楼-- · 2019-08-13 03:46

Within the JMS client code handling of the receive buffer us handled automatically; the theory is that specific error should never be received by a JMS Application.

The first snippet of code is the Java Classes API and this could get that error.

How big actually are these messages? What level of the JMS client code are you using - make sure that it is the latest version. And certainly one of the 7.5 or 8 releases.

This answer also has some more information on this.

查看更多
登录 后发表回答