虽然记录为针对Glassfish进行测试,但Glassfish中使用Message Driven Beans的IBM本机MQ资源适配器(wmq.jmsra.rar)远非显而易见。 EJB和JCA标准定义的许多标准配置工具实际上都不起作用,特别是关于激活规范。
我知道三个用于glassfish的MQ适配器:一个是来自Oracle的 GenericJMSRA :here和here。第二个是来自IBM(installation notes)的 wmq.jmsra ,可从* IBM Fix Central *获得。要使用它,您必须拥有要连接到的队列管理器的MQ许可证,但您可以使用免费的IBM ID进行下载。我正在使用IBM的第二个资源适配器,因为它提供了对java中的本机MQ API的访问,这是为了将精确制作的MQ消息发送到某些纯MQ(非JMS)目标。
存在第三种 - 传统 - 替代: JMSJCA here,曾经是我的最爱,但支持在Glassfish 3和JRE6的MQ V6停止。我试图将源代码升级到MQ v7.5(或V8 = JMS2.0),使用Glassfish 4(= JMS2.0)中的JRE7,甚至降低到glassfish 3.1(= JMS1.1),但在类加载器问题上失败了,一旦解决了,类转换异常/不兼容的连接对象版本等。
我终于让IBM RA工作在一个狭窄的配置中,我在回复帖子中记录。如果有人发现其他补救措施和配置也起作用,特别是避免了下面引起的一些陷阱,那将是非常受欢迎的。
这里是遇到的主要问题的快速列表:
Resource [ jms/MyAdminObj ] of type [ aor ] is not enabled
:已解决here MQException: JMSCMQ0001: ... ('MQRC_HOST_NOT_AVAILABLE')
引起的JMSWMQ0018: Failed to connect to queue manager '' with connection mode 'Client' and host name 'localhost(1414)'
...尽管您可以了解相关的remote_host-port-channel-queueManager详细信息在创建的连接池中是否已就位,或者甚至是ra中的默认值正在部署的RA的.xml Exception during endpoint activation for ra [ jmsra ], activationSpecClass [ com.sun.messaging.jms.ra.ActivationSpec ]
...揭示您的激活规范实际上已路由到内部JMS资源适配器而不是您认为应该的MQ资源适配器WARN j.e.r.r.com.sun.enterprise.connectors.util - RAR8000 : The method setConnectionFactoryLookup is not present in the class : com.sun.messaging.jms.ra.ActivationSpec
和WARN j.e.r.r.com.sun.enterprise.connectors.util - RAR8000 : The method setConnectionFactoryLookup is not present in the class : com.sun.messaging.jms.ra.ActivationSpec
随后成功部署了Message Driven Bean,可能让您相信,除非您密切关注服务器日志,否则您的MDB正在侦听正确的目标。但实际上并不会消费一条消息找到存储相关文档的地方也是一项混乱的工作。这是:
可以在MQ Websphere 7.5信息中心>中找到MQ v7.5中wmq.jmsra ra.xml中所有参数含义的线索。参考> ... Properties of WebSphere MQ classes for JMS objects MQ Websphere 7.5信息中心记录了资源适配器的使用> ...... The WebSphere MQ resource adapter但不会严格按照文件记录
答案 0 :(得分:1)
以下是我目前发现的一系列步骤,它们分别使用一对输入和输出消息驱动bean来与IBM MQ wmq.jmsra适配器一起使用。
首先,请务必安装兼容版本,例如:
对于出站端,请按以下步骤操作:
wmq.jmsra.rar
;无需更新任何ra.xml配置属性。足以尝试出站连接。使用EJB3.1注释,以下代码片段可以完成这项工作:
你班级范围内的:
@Resource(mappedName = "jms/QM_BHDEV_QCF")
private QueueConnectionFactory brokerQCF;
然后在方法范围内:
QueueConnection queueConn = null;
QueueSession queueSession = null;
QueueSender sender = null;
String queueUrl = "queue:///TEST.Q4?persistence=-1"; // cf. url-open MQ URL IBM format, or use a plain MQ queue name and set parameters via java API.
try {
queueConn = brokerQCF.createQueueConnection();
queueSession = queueConn.createQueueSession(true, queueSession.SESSION_TRANSACTED);
sender = queueSession.createSender(queueSession.createQueue(queueUrl));
TextMessage txtMsg = queueSession.createTextMessage();
txtMsg.setText("helllo world");
sender.send(txtMsg);
sender.close();
queueSession.close();
queueConn.close();
} catch (JMSException e) {
// error handling ...
}
在入站端,您需要一个激活规范。 wmq.jmsra连接工厂将不允许您使用注释指定相关的MQ连接池(例如EJB3.1规范中的“connectionFactoryLookup”激活配置属性)。您必须将glassfish-ejb-jar.xml部署描述符与EJB注释相结合。此外,我注意到引用的连接池中的所有队列管理器定义参数都被忽略,您必须在激活配置属性(如下所示)或{{1}中显式重新指定它们。部署描述符。最后但并非最不重要的一点是,您不会忘记所需的受管理对象(用于侦听的MQ目标)将(神秘地)未启用,并且需要额外的步骤来解决此问题。
请按照以下步骤操作:
ejb-jar.xml
的domain.xml;更改为“true”或删除属性。<admin-object-resource enabled="false"
命令)如下:
asadmin list-jndi-entries
然后,您可以使用以下激活规范和代码提取来侦听MQ队列:
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>connectorMQin</ejb-name>
<jndi-name>jms/testq1</jndi-name>
<mdb-connection-factory>
<jndi-name>jms/QM_BHDEV_QCF</jndi-name>
</mdb-connection-factory>
<mdb-resource-adapter>
<resource-adapter-mid>wmq.jmsra</resource-adapter-mid>
</mdb-resource-adapter>
</ejb>
</enterprise-beans>
</glassfish-ejb-jar>
......这对我有用。
缺陷是:整个配置细节现已硬连线到源代码中。有十几个连接,并且因为(据我所知)EL表达式在这个源代码中不起作用,您可能希望将所有激活属性(包括指向要侦听的队列的映射名称)重新定位到相应的ejb-jar.xml中元素,然后您将能够使用变体ejb-jar.xml模板构建连接器实例...
?有没有一个更好的建议或替代方案,以避免这种不必要的复杂性? (提醒我观察到出站/工厂端处理好的连接池属性在入站/激活端被忽略...)