java javax.jms.JMSSecurityException: MQJMS2008: 无法打开 MQ 队列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5654547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue
提问by Chris K
I have a JMS-based application that I am running in on Websphere 6.0, and am migrating to Websphere 7. Both Websphere servers are backed with a Websphere MQ 6.0 server. I receive the following exception when attempting to deploy a test servlet to the Websphere 7 server:
我有一个基于 JMS 的应用程序,我在 Websphere 6.0 上运行它,并且正在迁移到 Websphere 7。两个 Websphere 服务器都支持 Websphere MQ 6.0 服务器。尝试将测试 servlet 部署到 Websphere 7 服务器时,我收到以下异常:
javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue
javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue
Websphere 6.0 : RHEL 5.3
Websphere 6.0:RHEL 5.3
Websphere 7.0.0.15: RHEL 5.3
Websphere 7.0.0.15:RHEL 5.3
Websphere MQ 6.0: Windows Server 2003
Websphere MQ 6.0:Windows Server 2003
Servlet Test Code:
Servlet 测试代码:
public class JMSTestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
String MQConnectionFactory, MQQueue;
public JMSTestServlet() {
super();
// TODO Auto-generated constructor stub
System.out.println("JMSTestServlet: loading");
URL urlProps = getClass().getClassLoader().getResource("META-INF/startup.properties");
Properties props = new Properties();
try
{
System.out.println("JMSTestServlet: loading properties");
props.load( urlProps.openStream() );
MQConnectionFactory = props.getProperty("MQConnectionFactory");
MQQueue = props.getProperty("MQQueue");
System.out.println("JMSTestServlet: loading properties ... done!");
sendMessage("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void sendMessage(String messageString) {
QueueConnectionFactory fact;
QueueConnection qConn = null;
try {
System.out.println("JMSTestServlet: creating context");
Context ctx = new InitialContext();
fact = (QueueConnectionFactory)ctx.lookup(MQConnectionFactory);
Destination destination = (Destination)ctx.lookup(MQQueue);
System.out.println("JMSTestServlet: creating QueueConnection");
qConn = fact.createQueueConnection();
QueueSession qSess = qConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer prod = qSess.createProducer(destination);
System.out.println("JMSTestServlet: sending Message");
TextMessage message = qSess.createTextMessage();
message.setText(messageString);
prod.send(message);
System.out.println("JMSTestServlet: done sendMessage()");
} catch ( JMSException ex ) {
ex.toString();
ex.printStackTrace();
ex.getLinkedException().toString();
ex.getLinkedException().printStackTrace();
} catch ( NamingException ex ) {
System.out.println("JMSTestServlet: naming exception " + ex.toString());
ex.printStackTrace();
} catch ( Exception ex ) {
System.out.println("JNDI API lookup failed: " + ex.toString());
ex.printStackTrace();
} finally {
System.out.println("JMSTestServlet: cleaning up sendMessage()");
try
{
if ( qConn != null ) qConn.close();
} catch (JMSException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String messageString = request.getParameter("message");
sendMessage(messageString);
} finally {
}
}
Properties file is:
属性文件是:
MQConnectionFactory=jms/QUEUECONNFACTORY
MQQueue=jms/QUEUE
When deployed to Websphere 6 I get messages in my remote queues. When I deploy to Websphere 7, I get:
部署到 Websphere 6 后,我会在远程队列中收到消息。当我部署到 Websphere 7 时,我得到:
[4/13/11 14:53:55:622 EDT] 0000005c ConnectionEve A J2CA0056I: The Connection Manager received a fatal connection error from the Resource Adapter for resource JMS$QUEUECONNFACTORY$JMSManagedConnection@15. The exception is: javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 'QUEUE'.
[4/13/11 14:53:55:622 EDT] 0000005c ConnectionEve W J2CA0206W: A connection error occurred. To help determine the problem, enable the Diagnose Connection Usage option on the Connection Factory or Data Source.
[4/13/11 14:53:55:623 EDT] 0000005c ConnectionEve A J2CA0056I: The Connection Manager received a fatal connection error from the Resource Adapter for resource jms/QUEUECONNFACTORY. The exception is: javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 'QUEUE'.
[4/13/11 14:53:55:625 EDT] 0000005c SystemErr R javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 'QUEUE'.
I'm pretty sure I've configured the queues and connection factories on both Websphere servers the same. I'm at a loss as to how to resolve this issue, and the Google is of no help.
我很确定我已经在两个 Websphere 服务器上配置了相同的队列和连接工厂。我不知道如何解决这个问题,谷歌也没有帮助。
Update 2011-04-15:
2011-04-15 更新:
I've extracted the following error from the logs:
我从日志中提取了以下错误:
com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'
com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2035'
I've read up on it at a few locations, and I really can't see where there's a difference between WAS 6 and WAS 7 to cause this issue.
我已经在几个地方阅读了它,但我真的看不出 WAS 6 和 WAS 7 之间的差异导致了这个问题。
I'm running Websphere on both Linux hosts as root. I have a root account created on the Windows machine with full permissions to the MQ installation:
我以 root 身份在两台 Linux 主机上运行 Websphere。我在 Windows 机器上创建了一个具有 MQ 安装完全权限的 root 帐户:
setmqaut -t qmgr -m QM_webspheremq -p root +all
setmqaut -t qmgr -m QM_webspheremq -p root +all
采纳答案by JoshMc
I'll take a shot at answering this old post since it has been "Bumped by Community user" every four months since January 2019.
我将尝试回答这个旧帖子,因为它自 2019 年 1 月以来每四个月“被社区用户撞到”。
First some background:
首先介绍一下背景:
WAS 6.0
- Included MQ jar files from Websphere MQ v5.3
- Depending on the specific version of WAS 6.0, the jars would be from Websphere MQ v5.3 CSD08 up to CSD14
WAS 7.0.0.15
- Is supposed to include WebSphere MQ JCA resource adapter Version 7.0.1.3 (the default behavior here would have been that of the MQ v5.3 jars), but because of a bug, if you upgraded from WAS 7.0.0.0 to WAS 7.0.0.15, the WebSphere MQ JCA resource adapter Version 7.0.0.0 which came with WAS 7.0.0.0 would stay in place.
是 6.0
- 包含来自 Websphere MQ v5.3 的 MQ jar 文件
- 根据 WAS 6.0 的特定版本,jar 将从 Websphere MQ v5.3 CSD08 到 CSD14
是 7.0.0.15
- 应该包括 WebSphere MQ JCA 资源适配器版本 7.0.1.3(此处的默认行为是 MQ v5.3 jar 的行为),但是由于错误,如果您从 WAS 7.0.0.0 升级到 WAS 7.0.0.15 ,随 WAS 7.0.0.0 一起提供的 WebSphere MQ JCA 资源适配器版本 7.0.0.0 将保持原样。
The difference:
区别:
With MQ v5.3 jar files, when you call
fact.createQueueConnection();
, a blank userid would be sent to the queue manager. If theSVRCONN
channel you connected to had a blankMCAUSER
attribute then the connection would be running under the authority of the user account the Windows MQ queue manager was running as. In other words you would get full authority to the the queue manager and all queues (full MQ admin authority).With MQ v7.0.0.0 resource adapter, when you call
fact.createQueueConnection();
the JVM process ID will be sent to the queue manager. If theSVRCONN
channel you connect to had a blankMCAUSER
attribute then the Windows MQ queue manager would attempt to run the connection under the authority of the JVM process ID. Based on the information in your question this would be the userroot
.
对于 MQ v5.3 jar 文件,当您调用 时
fact.createQueueConnection();
,将向队列管理器发送一个空白用户标识。如果SVRCONN
您连接到的通道具有空白MCAUSER
属性,则该连接将在运行 Windows MQ 队列管理器的用户帐户的权限下运行。换句话说,您将获得对队列管理器和所有队列的完全权限(完全 MQ 管理权限)。使用 MQ v7.0.0.0 资源适配器,当您调用
fact.createQueueConnection();
JVM 进程 ID 时将发送到队列管理器。如果SVRCONN
您连接的通道具有空白MCAUSER
属性,则 Windows MQ 队列管理器将尝试在 JVM 进程 ID 的权限下运行连接。根据您问题中的信息,这将是 userroot
。
Summary:
概括:
It worked under Websphere 6.0 because the connection runs with full MQ Admin authority.
它在 Websphere 6.0 下工作,因为连接以完整的 MQ Admin 权限运行。
It failed under Websphere 7.0.0.15 because the connection runs with root
user authority, and in this case you only provided the root
user with all
authority to the queue manager (qmgr
) itself, but no authority to the QUEUE
.
它在 Websphere 7.0.0.15 下失败,因为连接以root
用户权限运行,在这种情况下,您只向root
用户提供了all
对队列管理器 ( qmgr
) 本身的权限,但没有对QUEUE
.
Websphere must first connect to and inquire the queue manager object before it would open any queues. The error you got was javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 'QUEUE'.
. This means that you did successfully connect to the queue manager, but then failed to connect to the queue.
Websphere 在打开任何队列之前必须首先连接到并查询队列管理器对象。你得到的错误是javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 'QUEUE'.
。这意味着您确实成功连接到队列管理器,但随后未能连接到队列。
This could have been fixed by providing authority for the QUEUE
to the root
user:
这可以通过为用户提供权限QUEUE
来解决root
:
setmqaut -t q -m QM_webspheremq -n QUEUE -p root +put +get +browse +inq +dsp
setmqaut -t q -m QM_webspheremq -n QUEUE -p root +put +get +browse +inq +dsp
Note all of the versions of software listed in the question are now (8.5 years later) out of support from IBM. It would also not be advisable to have a SVRCONN
channel with a blank MCAUSER
unless you were using some other method such as a security exit to set the MCAUSER to a non-MQ Admin id. In current IBM MQ versions you can use TLS with a client cert mapped on the queue manager to a non-MQ Admin id, or TLS without a cert + connection authentication to validate a user id and password sent by the client at the queue manager.
请注意,问题中列出的所有软件版本现在(8.5 年后)都不再受 IBM 支持。除非您使用其他方法(例如安全出口)将 MCAUSER 设置为非 MQ 管理员 ID,否则也不建议SVRCONN
使用空白的通道MCAUSER
。在当前的 IBM MQ 版本中,您可以使用 TLS 和映射到队列管理器上的客户端证书到非 MQ 管理员 ID,或使用没有证书 + 连接身份验证的 TLS 来验证客户端在队列管理器上发送的用户 ID 和密码。
回答by Chinmoy
I was getting the same error too. Check your port,queuemanager and queue details.For me it was the channel which was not correct.
我也遇到了同样的错误。检查您的端口、队列管理器和队列详细信息。对我而言,这是不正确的通道。
For other users: When you have MQJMS2008, you have no permissions to manipulate that queue, you must get a nested Exception that gives you more information about your error, and it tells you a MQRC Reason Code and Termination Code.
对于其他用户:当您拥有 MQJMS2008 时,您没有操作该队列的权限,您必须获得一个嵌套的异常,它为您提供有关您的错误的更多信息,并告诉您 MQRC 原因代码和终止代码。
For more info about the Reason Code, open a CMD and type mqrc
有关原因代码的更多信息,请打开 CMD 并键入 mqrc
Analiyzing your error, looks you are permitted to access that queue, i have some questions:
分析您的错误,看起来您被允许访问该队列,我有一些问题:
Are you connecting using JNDI? If you are connecting with a class that makes PTP connecting (i mean not using JNDI), you must provide the MQQueueConnectionFactory the channel, the queue manager, the queue name, and the hostname of the server, if you wanna know more about PTP connections, here is: http://hursleyonwmq.wordpress.com/2007/05/29/simplest-sample-applications-using-websphere-mq-jms/.
您是否使用 JNDI 进行连接?如果您正在使用使 PTP 连接的类(我的意思是不使用 JNDI)进行连接,则必须向 MQQueueConnectionFactory 提供通道、队列管理器、队列名称和服务器的主机名,如果您想了解更多关于 PTP 连接的信息,这里是:http: //hursleyonwmq.wordpress.com/2007/05/29/simplest-sample-applications-using-websphere-mq-jms/。
If you are doing this with a remote queue and you are using MQSeries and not WMQ on Windows, you must grant to public all privilegies. Use WRKMQMQ.
如果您使用远程队列执行此操作,并且您在 Windows 上使用 MQSeries 而不是 WMQ,您必须将所有特权授予公共。使用 WRKMQMQ。
If you can give the nested exception, i will help you.
如果您可以给出嵌套异常,我会帮助您。