两个简单的 IBM MQ 客户端测试写入 MQ 队列 - 为什么一个有效,但另一个无效?
Two simple IBM MQ client tests write to MQ queue - why does one work, but, NOT the other?
我正在 运行 两 (2) 个客户端测试。
大概他们都应该工作。但是,一个没有,我不知道为什么。
(1) 这个有效...
package aaa.bbb.ccc;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
public class MQCheck {
public static void main(String args[]) {
try {
int openOptions = CMQC.MQOO_INQUIRE | CMQC.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT;
MQEnvironment.hostname = "localhost";
MQEnvironment.port = 1414;
MQEnvironment.channel = "DEV.APP.SVRCONN";
MQEnvironment.properties.put(CMQC.USER_ID_PROPERTY, "admin");
MQEnvironment.properties.put(CMQC.PASSWORD_PROPERTY, "passw0rd");
MQEnvironment.properties.put(CMQC.TRANSPORT_PROPERTY, CMQC.TRANSPORT_MQSERIES);
MQQueueManager qMgr;
qMgr = new MQQueueManager("QM1");
MQQueue destQueue = qMgr.accessQueue("mylocalqueue", openOptions);
MQMessage hello_world = new MQMessage();
hello_world.writeUTF("Blah...blah...bleah...test message no.1...!");
MQPutMessageOptions pmo = new MQPutMessageOptions();
destQueue.put(hello_world, pmo);
destQueue.close();
qMgr.disconnect();
System.out.println("------------------------success...");
} catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
}
}
}
(2) 这个不行...
package aaa.bbb.ccc;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQSession;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
public class MQCheck3 {
public static void main(String args[]) {
Connection qconn = null;
QueueSession qsess = null;
MQSession mqsess;
Queue queue = null;
try {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
connectionFactory.setHostName("localhost");
connectionFactory.setChannel("DEV.APP.SVRCONN");//communications link
connectionFactory.setPort(1414);
connectionFactory.setQueueManager("QM1");
connectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
connectionFactory.setBooleanProperty(WMQConstants.CAPABILITY_USERNAME_PASSWORD, true);
connectionFactory.setStringProperty(WMQConstants.USERID, "admin");
connectionFactory.setStringProperty(WMQConstants.PASSWORD, "passw0rd");
qconn = (MQQueueConnection) connectionFactory.createConnection();
qconn = connectionFactory.createQueueConnection();
qconn.start();
mqsess = (MQSession) qconn.createSession(false, Session.AUTO_ACKNOWLEDGE); //.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = mqsess.createQueue("mylocalqueue");
TextMessage textMessage = mqsess.createTextMessage("Bleah...bleah...blech...test message no.2...!");
MessageProducer mc = mqsess.createProducer(queue);
mc.send(textMessage, 0, 0, 0);
System.out.println("------------------------success...");
} catch (JMSException e) {
System.out.println("Exception: " + e);
e.printStackTrace();
} finally {
try {
qsess.close();
qconn.close();
} catch (JMSException e) {
System.err.print(e);
}
}
}
}
注意:
运行 (2) 中的代码出现以下异常...
Exception: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QM1' with connection mode 'Client' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QM1' with connection mode 'Client' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:514)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:214)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:408)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6398)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:5740)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:293)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:234)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:111)
at aaa.bbb.ccc.MQCheck3.main(MQCheck3.java:35)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:202)
... 8 more
Exception in thread "main" java.lang.NullPointerException
at aaa.bbb.ccc.MQCheck3.main(MQCheck3.java:48)
*问题:任何人都可以向我解释为什么第二个示例不起作用吗?:*
-代码中是否遗漏了某些不正确的东西 and/or 使其能够正常工作?
仅供参考 - 来自 Docker 图片的 运行 MQ 服务器:
C:>docker 执行 mq dspmqver
C:\>docker exec mq dspmqver
Name: IBM MQ
Version: 9.0.3.0
Level: p903-L170517.DE
BuildType: IKAP - (Production)
Platform: IBM MQ for Linux (x86-64 platform)
Mode: 64-bit
O/S: Linux 4.9.31-moby
InstName: Installation1
InstDesc:
Primary: Yes
InstPath: /opt/mqm
DataPath: /var/mqm
MaxCmdLevel: 903
LicenseType: Developer
C:\>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>aaa.bbb.ccc</groupId>
<artifactId>mqcheck</artifactId>
<version>1</version>
<packaging>jar</packaging>
<name>mqcheck</name>
<description>mqcheck</description>
<properties>
<mq.version>8.0.0.2</mq.version>
</properties>
<dependencies>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>fscontext</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>jms</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mqjms</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq.jmqi</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq.headers</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq.commonservices</artifactId>
<version>${mq.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
</project>
根据下面post中的建议(thx,joshmc),这里是AMQERR01.log
它似乎提供了一个线索...-现在,确定如何解锁 'admin' 用户的任务:-)
----- cmqxrmsa.c : 1347 -------------------------------------------------------
08/11/17 17:32:09 - Process(1847.6) User(root) Program(amqrmppa)
Host(bd069b8075db) Installation(Installation1)
VRMF(9.0.3.0) QMgr(QM1)
Time(2017-08-11T17:32:09.967Z)
AMQ9776: Channel was blocked by userid
EXPLANATION:
The inbound channel 'DEV.APP.SVRCONN' was blocked from address '172.17.0.1'
because the active values of the channel were mapped to a userid which should
be blocked. The active values of the channel were 'MCAUSER(admin)
CLNTUSER(admin)'.
ACTION:
Contact the systems administrator, who should examine the channel
authentication records to ensure that the correct settings have been
configured. The ALTER QMGR CHLAUTH switch is used to control whether channel
authentication records are used. The command DISPLAY CHLAUTH can be used to
query the channel authentication records.
----- cmqxrmsa.c : 1347 -------------------------------------------------------
运行 按照命令(按照建议)...
C:\>docker exec --tty --interactive mq runmqsc
5724-H72 (C) Copyright IBM Corp. 1994, 2017.
Starting MQSC for queue manager QM1.
DIS CHL(DEV.APP.SVRCONN) MCAUSER
DIS CHL(DEV.APP.SVRCONN) MCAUSER
1 : DIS CHL(DEV.APP.SVRCONN) MCAUSER
AMQ8414: Display Channel details.
CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN)
MCAUSER(app)
:
显示 CHLAUTH(DEV.APP.SVRCONN) 匹配(RUNCHECK) 所有地址(172.17.0.1)
DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
5 : DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.APP.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(*) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-11)
ALTTIME(19.23.31)
DIS QMGR CONNAUTH
DIS QMGR CONNAUTH
1 : DIS QMGR CONNAUTH
AMQ8408: Display Queue Manager details.
QMNAME(QM1) CONNAUTH(DEV.AUTHINFO)
DIS AUTHINFO(DEV.AUTHINFO)
DIS AUTHINFO(DEV.AUTHINFO)
2 : DIS AUTHINFO(DEV.AUTHINFO)
AMQ8566: Display authentication information details.
AUTHINFO(DEV.AUTHINFO) AUTHTYPE(IDPWOS)
ADOPTCTX(YES) DESCR( )
CHCKCLNT(REQDADM) CHCKLOCL(OPTIONAL)
FAILDLAY(1) AUTHENMD(OS)
ALTDATE(2017-08-14) ALTTIME(13.57.29)
显示 CHLAUTH(DEV.APP.SVRCONN) 所有
DISPLAY CHLAUTH(DEV.APP.SVRCONN) all
1 : DISPLAY CHLAUTH(DEV.APP.SVRCONN) all
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.APP.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(*) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-16)
ALTTIME(13.43.26)
显示 CHLAUTH() 全部*
DISPLAY CHLAUTH(*) all
2 : DISPLAY CHLAUTH(*) all
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.ADMIN.SVRCONN) TYPE(USERMAP)
DESCR(Allows admin user to connect via ADMIN channel)
CUSTOM( ) ADDRESS( )
CLNTUSER(admin) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-16)
ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.ADMIN.SVRCONN) TYPE(BLOCKUSER)
DESCR(Allows admins on ADMIN channel) CUSTOM( )
USERLIST(nobody) WARN(NO)
ALTDATE(2017-08-16) ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.APP.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(*) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-16)
ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(MY.ADMIN.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(127.0.0.1) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-11)
ALTTIME(20.17.14)
AMQ8878: Display channel authentication record details.
CHLAUTH(MY.ADMIN.SVRCONN) TYPE(BLOCKUSER)
DESCR( ) CUSTOM( )
USERLIST(*NOBODY) WARN(NO)
ALTDATE(2017-08-11) ALTTIME(20.17.51)
AMQ8878: Display channel authentication record details.
CHLAUTH(SYSTEM.ADMIN.SVRCONN) TYPE(ADDRESSMAP)
DESCR(Default rule to allow MQ Explorer access)
CUSTOM( ) ADDRESS(*)
USERSRC(CHANNEL) CHCKCLNT(ASQMGR)
ALTDATE(2017-08-03) ALTTIME(17.22.22)
AMQ8878: Display channel authentication record details.
CHLAUTH(SYSTEM.*) TYPE(ADDRESSMAP)
DESCR(Default rule to disable all SYSTEM channels)
CUSTOM( ) ADDRESS(*)
USERSRC(NOACCESS) WARN(NO)
ALTDATE(2017-08-03) ALTTIME(17.22.22)
AMQ8878: Display channel authentication record details.
CHLAUTH(*) TYPE(ADDRESSMAP)
DESCR(Back-stop rule - Blocks everyone)
CUSTOM( ) ADDRESS(*)
USERSRC(NOACCESS) WARN(NO)
ALTDATE(2017-08-16) ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(*) TYPE(BLOCKUSER)
DESCR(Default rule to disallow privileged users)
CUSTOM( ) USERLIST(*MQADMIN)
WARN(NO) ALTDATE(2017-08-03)
ALTTIME(17.22.22)
reason '2035' ('MQRC_NOT_AUTHORIZED')
可能是由很多问题引起的。
IBM 支持技术说明“WMQ 7.1 / 7.5 / 8.0 / 9.0 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 or JMSWMQ2013 when using client connection as an MQ Administrator”有一篇关于诊断和解决此类问题的好文章。
如果您需要更具体的帮助,首先请通过编辑并添加到您的问题中来提供以下详细信息。
- 客户端应用程序使用的 JMS 的 IBM MQ 类 版本。
- IBM MQ 队列管理器上安装的 IBM MQ 版本
- 队列管理器 AMQERR01.LOG 中的错误与您在 IBM MQ 类 for JMS 客户端应用程序中收到的错误同时发生。
根据您在 AMQERR01.LOG
中遇到的错误,您有一个 CHLAUTH
规则阻止了您。 运行执行以下命令查看这是哪个规则:
DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
如果阻止 MQ 管理用户连接是默认规则,那么从安全角度来看这是一件好事。让应用程序作为低特权且没有 MQ 管理权限的 USERID 连接到队列管理器要好得多。为此,您需要授予用户连接到队列管理器以及从所需队列连接到 PUT
或 GET
的权限。
看了到目前为止的输出,我想是这样的。
用于 Java 程序的 IBM MQ 类 实际上并未验证为管理员用户,而是默认为 SVRCONN 通道上的 MCAUSER(app),这不是MQ 管理用户因此不会被阻止。问题是 MQEnvironment.properties
是为了保存属性的哈希值 table 而不是单个属性。查看@Roger 对“Java program to connect WMQ with User Id instead of channel”的回答,了解使用线程安全的 Hashtable 的示例,而 MQEnvironment 则不是。但是在解决这个问题时,Java 应用程序的 IBM MQ 类 应该像 JMS 应用程序一样被阻止。
IBM MQ 类 for JMS 程序正确验证为管理员用户并且设置了 ADOPTCTX(YES) 并且管理员用户是 MQ 管理用户因此被以下阻止默认 CHLAUTH 规则:
CHLAUTH(*) TYPE(BLOCKUSER)
DESCR(Default rule to disallow privileged users)
CUSTOM( ) USERLIST(*MQADMIN)
WARN(NO)
请通过运行以下内容进行验证:
DIS QMGR CONNAUTH
然后 运行 以下命令将值 SYSTEM.DEFAULT.AUTHINFO.IDPWOS
替换为在上述命令的输出中找到的值(如果不同):
DIS AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
请注意,我不确定为什么 RUNCHECK
没有返回 BLOCKUSER
规则,我没有 9.0.3 可以尝试,但有一个类似的 ADDRESSMAP
规则返回给你的那个我仍然在 8.0.0.5 和 8.0.0.6 上得到 BLOCKUSER
规则。
我正在 运行 两 (2) 个客户端测试。
大概他们都应该工作。但是,一个没有,我不知道为什么。
(1) 这个有效...
package aaa.bbb.ccc;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
public class MQCheck {
public static void main(String args[]) {
try {
int openOptions = CMQC.MQOO_INQUIRE | CMQC.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT;
MQEnvironment.hostname = "localhost";
MQEnvironment.port = 1414;
MQEnvironment.channel = "DEV.APP.SVRCONN";
MQEnvironment.properties.put(CMQC.USER_ID_PROPERTY, "admin");
MQEnvironment.properties.put(CMQC.PASSWORD_PROPERTY, "passw0rd");
MQEnvironment.properties.put(CMQC.TRANSPORT_PROPERTY, CMQC.TRANSPORT_MQSERIES);
MQQueueManager qMgr;
qMgr = new MQQueueManager("QM1");
MQQueue destQueue = qMgr.accessQueue("mylocalqueue", openOptions);
MQMessage hello_world = new MQMessage();
hello_world.writeUTF("Blah...blah...bleah...test message no.1...!");
MQPutMessageOptions pmo = new MQPutMessageOptions();
destQueue.put(hello_world, pmo);
destQueue.close();
qMgr.disconnect();
System.out.println("------------------------success...");
} catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
}
}
}
(2) 这个不行...
package aaa.bbb.ccc;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQSession;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
public class MQCheck3 {
public static void main(String args[]) {
Connection qconn = null;
QueueSession qsess = null;
MQSession mqsess;
Queue queue = null;
try {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
connectionFactory.setHostName("localhost");
connectionFactory.setChannel("DEV.APP.SVRCONN");//communications link
connectionFactory.setPort(1414);
connectionFactory.setQueueManager("QM1");
connectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
connectionFactory.setBooleanProperty(WMQConstants.CAPABILITY_USERNAME_PASSWORD, true);
connectionFactory.setStringProperty(WMQConstants.USERID, "admin");
connectionFactory.setStringProperty(WMQConstants.PASSWORD, "passw0rd");
qconn = (MQQueueConnection) connectionFactory.createConnection();
qconn = connectionFactory.createQueueConnection();
qconn.start();
mqsess = (MQSession) qconn.createSession(false, Session.AUTO_ACKNOWLEDGE); //.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = mqsess.createQueue("mylocalqueue");
TextMessage textMessage = mqsess.createTextMessage("Bleah...bleah...blech...test message no.2...!");
MessageProducer mc = mqsess.createProducer(queue);
mc.send(textMessage, 0, 0, 0);
System.out.println("------------------------success...");
} catch (JMSException e) {
System.out.println("Exception: " + e);
e.printStackTrace();
} finally {
try {
qsess.close();
qconn.close();
} catch (JMSException e) {
System.err.print(e);
}
}
}
}
注意: 运行 (2) 中的代码出现以下异常...
Exception: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QM1' with connection mode 'Client' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QM1' with connection mode 'Client' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:514)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:214)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:408)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6398)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:5740)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:293)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:234)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:111)
at aaa.bbb.ccc.MQCheck3.main(MQCheck3.java:35)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:202)
... 8 more
Exception in thread "main" java.lang.NullPointerException
at aaa.bbb.ccc.MQCheck3.main(MQCheck3.java:48)
*问题:任何人都可以向我解释为什么第二个示例不起作用吗?:*
-代码中是否遗漏了某些不正确的东西 and/or 使其能够正常工作?
仅供参考 - 来自 Docker 图片的 运行 MQ 服务器:
C:>docker 执行 mq dspmqver
C:\>docker exec mq dspmqver
Name: IBM MQ
Version: 9.0.3.0
Level: p903-L170517.DE
BuildType: IKAP - (Production)
Platform: IBM MQ for Linux (x86-64 platform)
Mode: 64-bit
O/S: Linux 4.9.31-moby
InstName: Installation1
InstDesc:
Primary: Yes
InstPath: /opt/mqm
DataPath: /var/mqm
MaxCmdLevel: 903
LicenseType: Developer
C:\>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>aaa.bbb.ccc</groupId>
<artifactId>mqcheck</artifactId>
<version>1</version>
<packaging>jar</packaging>
<name>mqcheck</name>
<description>mqcheck</description>
<properties>
<mq.version>8.0.0.2</mq.version>
</properties>
<dependencies>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>fscontext</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>jms</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mqjms</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq.jmqi</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq.headers</artifactId>
<version>${mq.version}</version>
</dependency>
<dependency>
<groupId>ibm.mq</groupId>
<artifactId>com.ibm.mq.commonservices</artifactId>
<version>${mq.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
</project>
根据下面post中的建议(thx,joshmc),这里是AMQERR01.log 它似乎提供了一个线索...-现在,确定如何解锁 'admin' 用户的任务:-)
----- cmqxrmsa.c : 1347 -------------------------------------------------------
08/11/17 17:32:09 - Process(1847.6) User(root) Program(amqrmppa)
Host(bd069b8075db) Installation(Installation1)
VRMF(9.0.3.0) QMgr(QM1)
Time(2017-08-11T17:32:09.967Z)
AMQ9776: Channel was blocked by userid
EXPLANATION:
The inbound channel 'DEV.APP.SVRCONN' was blocked from address '172.17.0.1'
because the active values of the channel were mapped to a userid which should
be blocked. The active values of the channel were 'MCAUSER(admin)
CLNTUSER(admin)'.
ACTION:
Contact the systems administrator, who should examine the channel
authentication records to ensure that the correct settings have been
configured. The ALTER QMGR CHLAUTH switch is used to control whether channel
authentication records are used. The command DISPLAY CHLAUTH can be used to
query the channel authentication records.
----- cmqxrmsa.c : 1347 -------------------------------------------------------
运行 按照命令(按照建议)...
C:\>docker exec --tty --interactive mq runmqsc
5724-H72 (C) Copyright IBM Corp. 1994, 2017.
Starting MQSC for queue manager QM1.
DIS CHL(DEV.APP.SVRCONN) MCAUSER
DIS CHL(DEV.APP.SVRCONN) MCAUSER
1 : DIS CHL(DEV.APP.SVRCONN) MCAUSER
AMQ8414: Display Channel details.
CHANNEL(DEV.APP.SVRCONN) CHLTYPE(SVRCONN)
MCAUSER(app)
:
显示 CHLAUTH(DEV.APP.SVRCONN) 匹配(RUNCHECK) 所有地址(172.17.0.1)
DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
5 : DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.APP.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(*) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-11)
ALTTIME(19.23.31)
DIS QMGR CONNAUTH
DIS QMGR CONNAUTH
1 : DIS QMGR CONNAUTH
AMQ8408: Display Queue Manager details.
QMNAME(QM1) CONNAUTH(DEV.AUTHINFO)
DIS AUTHINFO(DEV.AUTHINFO)
DIS AUTHINFO(DEV.AUTHINFO)
2 : DIS AUTHINFO(DEV.AUTHINFO)
AMQ8566: Display authentication information details.
AUTHINFO(DEV.AUTHINFO) AUTHTYPE(IDPWOS)
ADOPTCTX(YES) DESCR( )
CHCKCLNT(REQDADM) CHCKLOCL(OPTIONAL)
FAILDLAY(1) AUTHENMD(OS)
ALTDATE(2017-08-14) ALTTIME(13.57.29)
显示 CHLAUTH(DEV.APP.SVRCONN) 所有
DISPLAY CHLAUTH(DEV.APP.SVRCONN) all
1 : DISPLAY CHLAUTH(DEV.APP.SVRCONN) all
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.APP.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(*) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-16)
ALTTIME(13.43.26)
显示 CHLAUTH() 全部*
DISPLAY CHLAUTH(*) all
2 : DISPLAY CHLAUTH(*) all
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.ADMIN.SVRCONN) TYPE(USERMAP)
DESCR(Allows admin user to connect via ADMIN channel)
CUSTOM( ) ADDRESS( )
CLNTUSER(admin) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-16)
ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.ADMIN.SVRCONN) TYPE(BLOCKUSER)
DESCR(Allows admins on ADMIN channel) CUSTOM( )
USERLIST(nobody) WARN(NO)
ALTDATE(2017-08-16) ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(DEV.APP.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(*) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-16)
ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(MY.ADMIN.SVRCONN) TYPE(ADDRESSMAP)
DESCR( ) CUSTOM( )
ADDRESS(127.0.0.1) USERSRC(CHANNEL)
CHCKCLNT(ASQMGR) ALTDATE(2017-08-11)
ALTTIME(20.17.14)
AMQ8878: Display channel authentication record details.
CHLAUTH(MY.ADMIN.SVRCONN) TYPE(BLOCKUSER)
DESCR( ) CUSTOM( )
USERLIST(*NOBODY) WARN(NO)
ALTDATE(2017-08-11) ALTTIME(20.17.51)
AMQ8878: Display channel authentication record details.
CHLAUTH(SYSTEM.ADMIN.SVRCONN) TYPE(ADDRESSMAP)
DESCR(Default rule to allow MQ Explorer access)
CUSTOM( ) ADDRESS(*)
USERSRC(CHANNEL) CHCKCLNT(ASQMGR)
ALTDATE(2017-08-03) ALTTIME(17.22.22)
AMQ8878: Display channel authentication record details.
CHLAUTH(SYSTEM.*) TYPE(ADDRESSMAP)
DESCR(Default rule to disable all SYSTEM channels)
CUSTOM( ) ADDRESS(*)
USERSRC(NOACCESS) WARN(NO)
ALTDATE(2017-08-03) ALTTIME(17.22.22)
AMQ8878: Display channel authentication record details.
CHLAUTH(*) TYPE(ADDRESSMAP)
DESCR(Back-stop rule - Blocks everyone)
CUSTOM( ) ADDRESS(*)
USERSRC(NOACCESS) WARN(NO)
ALTDATE(2017-08-16) ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
CHLAUTH(*) TYPE(BLOCKUSER)
DESCR(Default rule to disallow privileged users)
CUSTOM( ) USERLIST(*MQADMIN)
WARN(NO) ALTDATE(2017-08-03)
ALTTIME(17.22.22)
reason '2035' ('MQRC_NOT_AUTHORIZED')
可能是由很多问题引起的。
IBM 支持技术说明“WMQ 7.1 / 7.5 / 8.0 / 9.0 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 or JMSWMQ2013 when using client connection as an MQ Administrator”有一篇关于诊断和解决此类问题的好文章。
如果您需要更具体的帮助,首先请通过编辑并添加到您的问题中来提供以下详细信息。
- 客户端应用程序使用的 JMS 的 IBM MQ 类 版本。
- IBM MQ 队列管理器上安装的 IBM MQ 版本
- 队列管理器 AMQERR01.LOG 中的错误与您在 IBM MQ 类 for JMS 客户端应用程序中收到的错误同时发生。
根据您在 AMQERR01.LOG
中遇到的错误,您有一个 CHLAUTH
规则阻止了您。 运行执行以下命令查看这是哪个规则:
DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
如果阻止 MQ 管理用户连接是默认规则,那么从安全角度来看这是一件好事。让应用程序作为低特权且没有 MQ 管理权限的 USERID 连接到队列管理器要好得多。为此,您需要授予用户连接到队列管理器以及从所需队列连接到 PUT
或 GET
的权限。
看了到目前为止的输出,我想是这样的。
用于 Java 程序的 IBM MQ 类 实际上并未验证为管理员用户,而是默认为 SVRCONN 通道上的 MCAUSER(app),这不是MQ 管理用户因此不会被阻止。问题是
MQEnvironment.properties
是为了保存属性的哈希值 table 而不是单个属性。查看@Roger 对“Java program to connect WMQ with User Id instead of channel”的回答,了解使用线程安全的 Hashtable 的示例,而 MQEnvironment 则不是。但是在解决这个问题时,Java 应用程序的 IBM MQ 类 应该像 JMS 应用程序一样被阻止。IBM MQ 类 for JMS 程序正确验证为管理员用户并且设置了 ADOPTCTX(YES) 并且管理员用户是 MQ 管理用户因此被以下阻止默认 CHLAUTH 规则:
CHLAUTH(*) TYPE(BLOCKUSER) DESCR(Default rule to disallow privileged users) CUSTOM( ) USERLIST(*MQADMIN) WARN(NO)
请通过运行以下内容进行验证:
DIS QMGR CONNAUTH
然后 运行 以下命令将值 SYSTEM.DEFAULT.AUTHINFO.IDPWOS
替换为在上述命令的输出中找到的值(如果不同):
DIS AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
请注意,我不确定为什么 RUNCHECK
没有返回 BLOCKUSER
规则,我没有 9.0.3 可以尝试,但有一个类似的 ADDRESSMAP
规则返回给你的那个我仍然在 8.0.0.5 和 8.0.0.6 上得到 BLOCKUSER
规则。