javax.jms.JMSSecurityException:MQJMS2008:无法打开 MQ 队列
我有一个基于 JMS 的应用程序,正在 Websphere 6.0 上运行,并且正在迁移到 Websphere 7。两个 Websphere 服务器均由 Websphere MQ 6.0 服务器提供支持。尝试将测试 servlet 部署到 Websphere 7 服务器时,我收到以下异常:
javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue
Websphere 6.0 : RHEL 5.3
Websphere 7.0.0.15:RHEL 5.3
Websphere MQ 6.0:Windows Server 2003
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 {
}
}
属性文件为:
MQConnectionFactory=jms/QUEUECONNFACTORY
MQQueue=jms/QUEUE
部署到 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'.
我很确定我已经在两个 Websphere 服务器上配置了相同的队列和连接工厂。我不知道如何解决这个问题,谷歌也没有帮助。
更新 2011-04-15:
我从日志中提取了以下错误:
com.ibm.mq.MQException:MQJE001:完成代码“2”,原因“2035”
我已经在几个位置阅读过它,但我真的看不出有什么区别WAS 6 和 WAS 7 之间的错误导致了此问题。
我在两台 Linux 主机上以 root 身份运行 Websphere。我在 Windows 计算机上创建了一个 root 帐户,具有 MQ 安装的完全权限:
setmqaut -t qmgr -m QM_webspheremq -p root +all
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我将尝试回答这篇旧帖子,因为自 2019 年 1 月以来,它每四个月就会被“社区用户碰撞”一次。
首先是一些背景知识:
WAS 6.0
WAS 7.0.0.15
区别:
对于 MQ v5.3 jar 文件,当您调用
fact.createQueueConnection();
时,将向队列管理器发送一个空白用户 ID。如果您连接的SVRCONN
通道具有空白的MCAUSER
属性,则该连接将在运行 Windows MQ 队列管理器的用户帐户的权限下运行。换句话说,您将获得队列管理器和所有队列的完全权限(完整的 MQ 管理权限)。使用 MQ v7.0.0.0 资源适配器,当您调用
fact.createQueueConnection();
时,JVM 进程 ID 将发送到队列管理器。如果您连接的SVRCONN
通道具有空白的MCAUSER
属性,则 Windows MQ 队列管理器将尝试在 JVM 进程 ID 的权限下运行连接。根据您问题中的信息,这将是用户root
。摘要:
它在 Websphere 6.0 下工作,因为连接以完全 MQ 管理员权限运行。
在 Websphere 7.0.0.15 下失败,因为连接以
root
用户权限运行,在这种情况下,您只为root
用户提供了all
权限队列管理器 (qmgr
) 本身,但没有QUEUE
的权限。Websphere 在打开任何队列之前必须首先连接并查询队列管理器对象。您收到的错误是
javax.jms.JMSSecurityException: MQJMS2008: 无法打开 MQ 队列“QUEUE”。
。这意味着您确实成功连接到队列管理器,但随后无法连接到队列。可以通过向
root
用户提供QUEUE
权限来解决此问题:setmqaut -tq -m QM_webspheremq -n QUEUE -p root +put +get + browser +inq +dsp
请注意,问题中列出的所有软件版本现在(8.5 年后)均不再获得 IBM 的支持。也不建议使用带有空白
MCAUSER
的SVRCONN
通道,除非您使用其他方法(例如安全出口)将 MCAUSER 设置为非 MQ管理员 ID。在当前的 IBM MQ 版本中,您可以使用带有在队列管理器上映射到非 MQ 管理员标识的客户端证书的 TLS,或者不带证书 + 连接身份验证的 TLS 来验证客户端在队列管理器处发送的用户标识和密码。I'll take a shot at answering this old post since it has been "Bumped by Community user" every four months since January 2019.
First some background:
WAS 6.0
WAS 7.0.0.15
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
.Summary:
It worked under Websphere 6.0 because the connection runs with full MQ Admin authority.
It failed under Websphere 7.0.0.15 because the connection runs with
root
user authority, and in this case you only provided theroot
user withall
authority to the queue manager (qmgr
) itself, but no authority to theQUEUE
.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.This could have been fixed by providing authority for the
QUEUE
to theroot
user: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 blankMCAUSER
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.我也遇到了同样的错误。检查您的端口、队列管理器和队列详细信息。对我来说,这是不正确的通道。
对于其他用户:
当您拥有 MQJMS2008 时,您无权操作该队列,您必须获得一个嵌套异常,它为您提供有关错误的更多信息,并告诉您 MQRC 原因代码和终止代码。
有关原因代码的更多信息,请打开 CMD 并输入 mqrc
分析您的错误,看起来您被允许访问该队列,我有一些问题:
您是否使用 JNDI 连接?如果您正在连接一个进行 PTP 连接的类(我的意思是不使用 JNDI),如果您想了解有关 PTP 连接的更多信息,则必须向 MQQueueConnectionFactory 提供通道、队列管理器、队列名称和服务器的主机名,这里是: http:// /hursleyonwmq.wordpress.com/2007/05/29/simplest-sample-applications-using-websphere-mq-jms/ 。
如果您使用远程队列执行此操作,并且您在 Windows 上使用 MQSeries 而不是 WMQ,则必须向 public 授予所有权限。
使用 WRKMQMQ。
如果您可以提供嵌套异常,我会帮助您。
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.
For more info about the Reason Code, open a CMD and type 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/ .
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.
If you can give the nested exception, i will help you.