[英]Two simple IBM MQ client tests write to MQ queue - why does one work, but, NOT the other?
I'm running two(2) client tests.我正在运行两(2)个客户端测试。
Presumably they should both work.据推测,他们都应该工作。 But, one does not, and I do not know why.
但是,一个没有,我不知道为什么。
(1) This one works... (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) This one does NOT work... (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);
}
}
}
}
NOTE: Running the code in (2) gets the following exception...注意:运行 (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)
*QUESTION: can anyone explain to me why the 2nd example does not work?: * *问题:谁能向我解释为什么第二个例子不起作用?:*
-Is there something that is incorrect and/or missing from the code that would enable it to work? - 代码中是否存在不正确和/或缺失的内容使其能够正常工作?
FYI - running MQ server from Docker image:仅供参考 - 从 Docker 镜像运行 MQ 服务器:
C:>docker exec mq dspmqver C:>docker exec 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 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>
as per the suggestion in the post below (thx, joshmc), here is the AMQERR01.log it appears to provide a clue... -now, the quest to determine how to I unblock the 'admin' user :-)根据下面帖子中的建议(thx,joshmc),这里是 AMQERR01.log,它似乎提供了一个线索...... - 现在,寻求确定如何解除对“管理员”用户的阻止:-)
----- 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 -------------------------------------------------------
running following command (as suggested)...运行以下命令(如建议)...
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
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)
:
DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1)显示CHLAUTH(DEV.APP.SVRCONN) MATCH(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 CONNAUT
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)
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)
DISPLAY CHLAUTH(DEV.APP.SVRCONN) all显示 CLAUTH(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)
DISPLAY CHLAUTH( ) all*显示克劳斯( ) 全部*
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)
The reason '2035' ('MQRC_NOT_AUTHORIZED')
can be caused by quite a few issues. reason '2035' ('MQRC_NOT_AUTHORIZED')
可能是由很多问题引起的。
IBM Support Technote " 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 " has a good write up on diagnosing and resolving issues like this. 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 ”有一篇关于诊断和解决此类问题的好文章。
If you want more specific help, to start with please provide the following details by editing and adding them to your question.如果您需要更具体的帮助,请首先通过编辑并将其添加到您的问题中来提供以下详细信息。
Based on the error you have in the AMQERR01.LOG
you have a CHLAUTH
rule that is blocking you.根据您在
AMQERR01.LOG
中的AMQERR01.LOG
您有一个阻止您的CHLAUTH
规则。 Run the following command to see which rule this is:运行以下命令以查看这是哪条规则:
DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
If it is the default rule that blocks MQ administrative users from connecting, then this is a good thing from a security standpoint.如果阻止 MQ 管理用户连接是默认规则,那么从安全角度来看,这是一件好事。 It is much better to have an application connect to the queue manager as a USERID that is low privileged and does not have MQ administrative authority.
最好让应用程序以低特权且没有 MQ 管理权限的 USERID 连接到队列管理器。 To do this you need to grant the user authority to connect to the queue manager as well as to
PUT
or GET
from the queues required.为此,您需要授予用户连接到队列管理器以及从所需队列执行
PUT
或GET
权限。
After looking at the output so far I think what is happening is this.在查看到目前为止的输出后,我认为正在发生的事情就是这样。
The IBM MQ Classes for Java program is not actually authenticating as the admin user and is being defaulted to the MCAUSER(app) on the SVRCONN channel which is not a MQ Administrative user so does not get blocked. IBM MQ Classes for Java 程序实际上并未以管理员用户身份进行身份验证,而是默认为 SVRCONN 通道上的 MCAUSER(app),该通道不是 MQ 管理用户,因此不会被阻止。 The issue is that the
MQEnvironment.properties
is meant to hold the value of a Hash table of properties not individual properties.问题在于
MQEnvironment.properties
旨在保存属性的哈希表的值,而不是单个属性。 Check out @Roger's answer to " Java program to connect WMQ with User Id instead of channel " for examples of using the Hashtable which is thread safe compared to the MQEnvironment which is not.查看@Roger 对“ 将 WMQ 与用户 ID 而不是通道连接的 Java 程序”的回答,了解使用线程安全的 Hashtable 与非 MQEnvironment 相比的示例。 But in fixing this issue the IBM MQ Classes for Java app should be blocked the same as the JMS app.
但是在解决此问题时,IBM MQ Classes for Java 应用程序应该像 JMS 应用程序一样被阻止。
The IBM MQ Classes for JMS program is properly authenticating as the admin user and ADOPTCTX(YES) is set and the admin user is a MQ Administrative user so is blocked by the following default CHLAUTH rule: IBM MQ Classes for JMS 程序正在以管理员用户身份正确进行身份验证,并且设置了 ADOPTCTX(YES),并且管理员用户是 MQ 管理用户,因此被以下默认 CHLAUTH 规则阻止:
CHLAUTH(*) TYPE(BLOCKUSER) DESCR(Default rule to disallow privileged users) CUSTOM( ) USERLIST(*MQADMIN) WARN(NO)
Please validate by running the following:请通过运行以下命令进行验证:
DIS QMGR CONNAUTH
Then run the following command replacing the value SYSTEM.DEFAULT.AUTHINFO.IDPWOS
with the value found in output of the above command if it is different:然后运行以下命令,将
SYSTEM.DEFAULT.AUTHINFO.IDPWOS
值替换为在上述命令的输出中找到的值(如果不同):
DIS AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
Note I'm not sure why the RUNCHECK
is not returning the BLOCKUSER
rule, I don't have a 9.0.3 to try this on but with a similar ADDRESSMAP
rule to the one that is being returned for you I still get the BLOCKUSER
rule on both 8.0.0.5 and 8.0.0.6.注意我不知道为什么
RUNCHECK
没有返回BLOCKUSER
规则,我没有 9.0.3 来尝试这个,但是与返回给你的规则相似的ADDRESSMAP
规则我仍然得到BLOCKUSER
规则在 8.0.0.5 和 8.0.0.6 上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.