【问题标题】:Connecting to IBM MQ using CCDT file in JMS在 JMS 中使用 CCDT 文件连接到 IBM MQ
【发布时间】:2018-02-08 16:39:15
【问题描述】:

我正在尝试使用 JMS 和客户端通道定义表 (CCDT) 连接到 IBM MQ。当我单独指定 MQ 属性时,我能够成功连接到 QueueManager。 但是当我尝试使用 CCDT 文件时,我得到了以下异常。

由于客户端通道定义表 (CCDT) 用于确定客户端应用程序用于连接到队列管理器的通道定义,因此我没有设置 QueueManager 名称。

ERROR> com.ssc.ach.mq.JMSMQReceiver[main]: errorMQJMS2005: failed to create MQQueueManager for ''
javax.jms.JMSException: MQJMS2005: failed to create MQQueueManager for ''
    at com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:586)
    at com.ibm.mq.jms.MQConnection.createQM(MQConnection.java:2110)
    at com.ibm.mq.jms.MQConnection.createQMNonXA(MQConnection.java:1532)
    at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:150)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:174)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:1066)

我使用.setCCDTURL(ccdt); 方法设置CCDT URL。

private MQQueueConnectionFactory  mqQueueConnectionFactory = new MQQueueConnectionFactory();
         mqQueueConnectionFactory.setCCDTURL(ccdt);
         queueConnection = mqQueueConnectionFactory.createConnection(username, pwd);

当我尝试使用以下配置而不是 CCDT 文件连接时,它会连接到 MQ。

         mqQueueConnectionFactory.setHostName(host);
         mqQueueConnectionFactory.setChannel(channel);
         mqQueueConnectionFactory.setPort(port);
         mqQueueConnectionFactory.setQueueManager(qManager);
         mqQueueConnectionFactory.setTransportType(1);

我是否需要设置 setQueueManager 以及 CCDT 文件,正如异常所说的 failed to create MQQueueManager for ''

【问题讨论】:

  • 您在频道表中定义的 CLNTCONN 频道的 QMNAME 字段中有什么内容?您是否在频道表中只定义了一个频道?
  • 在 TAB 文件中,我看到加密的数据和主机名、端口号、通道名称
  • 你安装了什么版本的mq客户端?
  • 我们正在使用 MQ 8

标签: java jms message-queue ibm-mq


【解决方案1】:

CCDT 不是用来在文本编辑器中读取的,它是一个二进制格式的文件。每个CLNTCONN 通道的CCDT 中的参数之一是QMNAME。了解 QMNAME 设置为什么以及您在 CCDT 中定义了多少 CLNTCONN 通道以及您想要完成的任务将有助于确定应该为 setQueueManager 指定的值。


如果只有一个CLNTCONN 频道,那么您可以指定以下内容,无论 QMNAME 属性设置为什么,它都将使用单个频道进行连接:

setQueueManager("*");

如果文件中有多个CLNTCONN 通道,每个通道都指定了不同的QMNAME,假设名称与在与通道关联的主机和端口上侦听的实际队列管理器名称匹配,您将传递队列管理器名称:

setQueueManager("QMGRNAME");

如果文件中有多个CLNTCONN 通道,每个通道都指定了相同的QMNAME,其中此名称并不意味着反映在与每个通道关联的主机和端口上侦听的实际队列管理器名称,这是称为队列管理器组,这将用于您希望客户端连接到任意数量的不同主机和端口并且您不需要知道要连接到哪个队列管理器,在这种情况下您将传递队列管理器以*为前缀的组名:

setQueueManager("*QMGRGROUPNAME");

上述的另一种变体是,如果文件中有多个CLNTCONN 通道,每个通道都指定了全空白(空格)或NULL QMNAME,这称为队列管理器组,这是有意的您希望客户端连接到任意数量的不同主机和端口,并且您不需要知道要连接到哪个队列管理器,在这种情况下,您可以将队列管理器名称作为单个空格 传递或什么都不传递在所有``:

setQueueManager(" ");
//or
setQueueManager("");

如果您根本不使用 setQueueManager,上面的最后一个用例可能会起作用。


如果您想查看 CCDT 的内容,您可以使用作为 MQ v8 和更高版本客户端或服务器安装一部分的 runmqsc 命令。

对于 Unix ksh/bash shell,请使用以下命令:

export MQCHLLIB=PATH/OF/CCDT
export MQCHLTAB=NAME_OF_CCDT
runmqsc -n

对于 Windows,请使用以下内容:

set MQCHLLIB=PATH/OF/CCDT
set MQCHLTAB=NAME_OF_CCDT
runmqsc -n

runmqsc 程序启动并显示Starting local MQSC for 'NAME_OF_CCDT'. 后,您可以运行以下命令查看通道详细信息:

DIS CHL(*)

以下是用于缩小返回字段数量的更具体的命令:

DIS CHL(*) QMNAME CONNAME

【讨论】:

  • 是的,我尝试添加 mqQueueConnectionFactory.setQueueManager("*QUEMANAGER") 它现在可以工作了。
  • @Nayeem 我添加了有关如何使用 MQ v8 或更高版本的信息 runmqsc 作为客户端和服务器安装的一部分来查看 CCDT 中的 CLNTCONN 通道定义的命令,这将允许您查看表中定义了多少通道,并在需要时对其进行更新(ALTER CHLDEFINE CHLDELETE CHL)。
  • 我实际上尝试添加 mqQueueConnectionFactory.setQueueManager("*QUEMANAGER") 在看到您的答案及其工作之前。但是您的回答很好地解释了我发布的问题。
  • @JoshMc 您好,需要您的帮助,我可以通过 CCDT 和 JMS 进行连接,但我有一种情况,我每次都必须读取 CCDt 文件以对 QueueManagers 进行负载平衡。但它一次又一次地重新初始化同一个文件。是否无法初始化 CCDT 文件一次,然后连接到备用队列管理器?
【解决方案2】:

我有一段时间没看它了,但我认为正确的格式是:

MQQueueConnectionFactory qcf = new MQQueueConnectionFactory();
qcf.setQueueManager(qManager);
qcf.setCCDTURL(ccdt);
conn = qcf.createConnection(username, pwd);

【讨论】:

  • 是的,我尝试添加 mqQueueConnectionFactory.setQueueManager("*QUEMANAGER") 它现在可以工作了。
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 2019-03-23
  • 2019-12-31
  • 1970-01-01
  • 2020-04-23
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多