【问题标题】:activation of message driven bean using IBM MQ 7.5 resource adapter (wmq.jmsra) in glassfish 3在 glassfish 3 中使用 IBM MQ 7.5 资源适配器 (wmq.jmsra) 激活消息驱动的 bean
【发布时间】:2015-11-06 10:16:23
【问题描述】:

虽然记录为针对 Glassfish 进行了测试,但 Glassfish 中的消息驱动 Beans 使用 IBM 本机 MQ 资源适配器 (wmq.jmsra.rar) 远非显而易见。 EJB 和 JCA 标准定义的许多标准配置工具实际上不起作用,尤其是在激活规范方面。

我知道 glassfish 的三个 MQ 适配器:一个是来自 Oracle 的 GenericJMSRAherehere。第二个是来自 IBM (installation notes) 的 wmq.jmsra,可从 * IBM Fix Central* 获得。要使用它,您必须确实拥有您将连接到的队列管理器的 MQ 许可证,但您可以使用免费的 IBM ID 下载。我正在使用 IBM 的第二个资源适配器,因为它提供了对 Java 中的本机 MQ API 的访问,我需要这些 API 来将精确制作的 MQ 消息发送到一些纯 MQ(非 JMS)目标。

存在第三种--legacy--alternative:JMSJCA here,曾经是我的最爱,但在 Glassfish 3 和 JRE6 中的 MQ V6 停止了支持。我尝试在 Glassfish 4 (=JMS2.0) 中使用 JRE7 将源代码升级到 MQ v7.5 (或 V8 = JMS2.0),甚至升级到 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 然后成功部署消息驱动 Bean,可能会让您相信,除非您密切关注服务器日志,否则您的 MDB 现在正在侦听正确的目的地......但实际上不会消耗单条消息

查找相关文档的存储位置也是一项繁琐的工作。这里是:

MQ v7.5中wmq.jmsra ra.xml中所有参数含义的线索可以在MQ Websphere 7.5 infocenter>参考>...Properties of WebSphere MQ classes for JMS objects 并且资源适配器的使用记录在 MQ Websphere 7.5 信息中心 > ... The WebSphere MQ resource adapter 但不会严格按照记录的方式工作

【问题讨论】:

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


    【解决方案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 下搜索key ==“资源适配器”并按照安装过程here(您将获得一个必须使用的jar 执行java -jar ...); docs here 和 ra.xml 配置属性 here
    3. 启动 glassfish Web 控制台并在“应用程序”下部署 IBM RA wmq.jmsra.rar;无需更新任何 ra.xml 配置属性。
    4. 仍然在控制台中,创建一个资源 > 连接器 > 连接池,您可以将队列管理器的常用 MQ 参数集附加到该连接池,例如:端口 1414、localAddress 10.0.0.66、failIfQuiesce true、hostName bhdev、queueManager QM_BHDEV、通道 BRK.SVRCONN。请务必选择所需的工厂类型,例如javax.jms.QueueConnectionFactory
    5. 然后创建资源 > 连接器 > 资源并为您刚刚创建的池提供 JNDI 名称,例如jms/QM_BHDEV_QCF

    这足以尝试出站连接。使用 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 注释结合起来。此外,我注意到引用的连接池中的所有队列管理器定义参数都将被忽略,您必须在激活配置属性(如下所示)或ejb-jar.xml 中明确重新指定它们部署描述符。最后但并非最不重要的一点是,您不应忘记(神秘地)不会启用所需的管理对象(用于 MQ 目标侦听),并且需要额外的步骤来解决此问题。

    按照以下步骤操作:

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

    如下:

    <!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>
    

    然后您可以使用以下激活规范和代码提取来监听 MQ 队列:

    @MessageDriven(name="connectorMQin",
    activationConfig = {
            @ActivationConfigProperty(propertyName="destination", propertyValue="TEST.Q1"),  
            @ActivationConfigProperty(propertyName="hostName", propertyValue="10.0.0.66"),  
            @ActivationConfigProperty(propertyName="port", propertyValue="1414"),  
            @ActivationConfigProperty(propertyName="queueManager", propertyValue="QM_BHDEV"),
            @ActivationConfigProperty(  propertyName ="destinationType", propertyValue = "javax.jms.Queue"),
            @ActivationConfigProperty(  propertyName ="clientId", propertyValue = "wmq.jmsra.id") }, 
    mappedName = "jms/testq1")
    @TransactionManagement(TransactionManagementType.BEAN)
    public class MqIn implements MessageListener {
    
     public void onMessage(Message in_msg) {
     // ...
     try {
        if (in_msg instanceof TextMessage) {
                    in_bodyText = ((TextMessage) in_msg).getText();
           // ... etc
        }
     } catch ( // ... etc
    

    ...这对我有用。

    缺陷是:整个配置细节现在已经硬连接到源代码中。有十几个连接,并且因为(据我所知)EL 表达式在此源代码中不起作用,您可能希望将所有激活属性(包括指向要侦听的队列的映射名称)重新定位到相应的 ejb-jar.xml元素,然后您将能够使用变体 ejb-jar.xml 模板构建连接器实例...

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

    【讨论】:

      猜你喜欢
      • 2021-07-01
      • 2013-09-26
      • 2012-07-21
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      • 2010-11-05
      相关资源
      最近更新 更多