javax.jms.JMSSecurityException: MQJMS2008: 未能打开 MQ 队列
Posted
技术标签:
【中文标题】javax.jms.JMSSecurityException: MQJMS2008: 未能打开 MQ 队列【英文标题】:javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 【发布时间】:2011-08-05 00:03:18 【问题描述】:我有一个基于 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: Completion Code '2', Reason '2035'
我已经在几个地方阅读过它,但我真的看不出 WAS 6 和 WAS 7 之间的差异在哪里导致了这个问题。
我在两台 Linux 主机上都以 root 身份运行 Websphere。我在 Windows 机器上创建了一个具有 MQ 安装完全权限的 root 帐户:
setmqaut -t qmgr -m QM_webspheremq -p root +all
【问题讨论】:
SecurityException 建议您需要提供连接凭据。 你会这么认为,但我似乎不需要它们。我没有为 Websphere 6.0(工作)配置任何内容,拥有/不拥有它们似乎对 Websphere 7 没有任何影响(!工作)。 嗨,克里斯,您是否介意查看我迟交的答案,如果看起来不错,请接受它或其他用户的回答,以防止这一次“被社区用户撞到”(可能是因为我提供了新的答案)它在仅仅 1 个月后就遇到了问题。 【参考方案1】:我也遇到了同样的错误。检查您的端口、队列管理器和队列详细信息。对我来说,这是不正确的通道。
对于其他用户: 当您拥有 MQJMS2008 时,您无权操作该队列,您必须获得一个嵌套的异常,它为您提供有关您的错误的更多信息,它告诉您一个 MQRC 原因代码和终止代码。
有关原因代码的更多信息,请打开 CMD 并键入 mqrc
分析您的错误,看起来您被允许访问该队列,我有一些问题:
您是否使用 JNDI 进行连接?如果您正在连接一个使 PTP 连接的类(我的意思是不使用 JNDI),您必须向 MQQueueConnectionFactory 提供通道、队列管理器、队列名称和服务器的主机名,如果您想了解更多关于 PTP 连接的信息,这里是:http://hursleyonwmq.wordpress.com/2007/05/29/simplest-sample-applications-using-websphere-mq-jms/。
如果您对远程队列执行此操作,并且您在 Windows 上使用的是 MQSeries 而不是 WMQ,则您必须授予公共所有权限。 使用 WRKMQMQ。
如果你能给出嵌套异常,我会帮你的。
【讨论】:
【参考方案2】:自 2019 年 1 月以来,每四个月“社区用户浏览”一次,我将尝试回答这个旧帖子。
先介绍一下背景:
是 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 将保持不变。区别:
对于 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
用户权限运行,在这种情况下,您仅向队列管理器 (qmgr
) 本身提供了具有 all
权限的 root
用户,但是没有QUEUE
的权限。
Websphere 必须首先连接并查询队列管理器对象,然后才能打开任何队列。你得到的错误是javax.jms.JMSSecurityException: MQJMS2008: failed to open MQ queue 'QUEUE'.
。这意味着您确实成功连接到队列管理器,但随后无法连接到队列。
这可以通过将QUEUE
的权限提供给root
用户来解决:
setmqaut -t q -m QM_webspheremq -n QUEUE -p root +put +get +browse +inq +dsp
请注意,问题中列出的所有软件版本现在(8.5 年后)都不再得到 IBM 的支持。也不建议使用带有空白MCAUSER
的SVRCONN
通道,除非您使用其他方法(例如安全出口)将 MCAUSER 设置为非 MQ Admin id。在当前的 IBM MQ 版本中,您可以使用 TLS 和在队列管理器上映射到非 MQ Admin id 的客户端证书,或使用没有证书 + 连接身份验证的 TLS 来验证客户端在队列管理器上发送的用户 id 和密码。
【讨论】:
接受。它是一个彻底的答案。但不完全确定它的有效性。我不再有能力进行测试,但如果有人仍然有这个问题,人们有其他人可以联系,或者可以查看的地方。感谢您的精彩文章。以上是关于javax.jms.JMSSecurityException: MQJMS2008: 未能打开 MQ 队列的主要内容,如果未能解决你的问题,请参考以下文章