使用glassfish 3中的IBM MQ 7.5资源适配器(wmq.jmsra)激活消息驱动Bean

时间:2015-08-13 12:31:52

标签: glassfish jms ibm-mq message-driven-bean

虽然记录为针对Glassfish进行测试,但Glassfish中使用Message Driven Beans的IBM本机MQ资源适配器(wmq.jmsra.rar)远非显而易见。 EJB和JCA标准定义的许多标准配置工具实际上都不起作用,特别是关于激活规范。

我知道三个用于glassfish的MQ适配器:一个是来自Oracle的 GenericJMSRA herehere。第二个是来自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工作在一个狭窄的配置中,我在回复帖子中记录。如果有人发现其他补救措施和配置也起作用,特别是避免了下面引起的一些陷阱,那将是非常受欢迎的。

这里是遇到的主要问题的快速列表:

  • 管理对象一旦创建了产量:RAR8029: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.ActivationSpecWARN 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但不会严格按照文件记录

1 个答案:

答案 0 :(得分:1)

以下是我目前发现的一系列步骤,它们分别使用一对输入和输出消息驱动bean来与IBM MQ wmq.jmsra适配器一起使用。

首先,请务必安装兼容版本,例如:

  • GF3(精确的GlassFish v3.1.2)与IBM MQ 7.5资源适配器和JRE7,共同支持JMS1.1。这是我在下面引用的配置。
  • 带有MQ 8 RA和JRE7或JRE8的GF4 ......在JMS2.0下也应该工作,但个人尚未测试

对于出站端,请按以下步骤操作:

  1. 安装Glassfish 3(docs here
  2. IBM fix central下载IBM MQ 7.5资源适配器,在“Websphere MQ”产品v7.5下搜索密钥==“资源适配器”并按照安装步骤here(你得到一个jar你必须用java -jar执行...); docs here和ra.xml配置属性here
  3. 启动glassfish Web控制台,在“应用程序”下部署IBM RA wmq.jmsra.rar;无需更新任何ra.xml配置属性。
  4. 仍然在控制台中,创建一个资源>连接器>连接池,您可以为队列管理器附加通常的MQ参数集,如:port 1414,localAddress 10.0.0.66,failIfQuiesce true,hostName bhdev,queueManager QM_BHDEV,channel BRK.SVRCONN。务必选择所需的工厂类型,例如了javax.jms.QueueConnectionFactory
  5. 然后创建一个资源>连接器>资源并为刚刚创建的池提供JNDI名称,例如JMS / QM_BHDEV_QCF
  6. 足以尝试出站连接。使用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目标)将(神秘地)未启用,并且需要额外的步骤来解决此问题。

    请按照以下步骤操作:

    1. 在glassfish管理控制台中,创建一个资源>连接器>要侦听的目标队列的Admin对象。不太关心物理队列名称等属性会过载!给它一个名字,例如'JMS / testq1'
    2. 即使您选中了相关的启用复选框,glassfish也会抱怨'aor'(管理对象资源)未启用;此外,如果您检查jndi树,则您的管理对象不存在。
    3. 停止glassfish,并编辑ejb-jar.xml的domain.xml;更改为“true”或删除属性。
    4. 重新启动glassfish并检查现在在JNDI中列出的管理对象(例如,使用<admin-object-resource enabled="false"命令)
    5. 将您的MDB(EJB 3.1)项目关联到glassfish运行时(可能需要您导入Glassfish的OEPE Eclipse插件,然后在eclipse中声明glassfish服务器和运行时目标),并生成/编辑glassfish- ejb-jar
    6. 如下:

      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模板构建连接器实例...

      ?有没有一个更好的建议或替代方案,以避免这种不必要的复杂性? (提醒我观察到出站/工厂端处理好的连接池属性在入站/激活端被忽略...)