SJSAS with GenericJMSRA

连接性 > 容器 > SJSAS with GenericJMSRA

使用 ActiveMQ Classic、Generic JMS RA 和 SJSAS (Glassfish)

本文档记录了使用 GenericJMSRA 使 ActiveMQ Classic 和 SJSAS 协同工作的方法。目标是将 ActiveMQ Classic 作为 JMS 提供者,并且 MDB 可以部署在 SJSAS 中,监听来自 ActiveMQ Classic 的消息。请注意,我使用的 SJSAS 版本是 9.0 Update 1。我没有时间用 SJSAS 9.1 或 Glassfish v2 测试它。

步骤

首先,下载所有二进制文件

  • genericra 1.7 (rar)
  • activemq 4.1.1 (zip 或 tar.gz)

activemq 有些依赖项,但是,您可以在发行版中轻松找到所有依赖项(zip 或 tar.gz)。以下是最低依赖项列表

  • activemq-core
  • activeio
  • commons-logging
  • backport-util-concurrent

为了使用 genericra,您需要首先使用 asadmin(SJSAS 的命令行工具)创建一个资源适配器配置。

asadmin create-resource-adapter-config
  --property
      SupportsXA=false
      :RMPolicy=OnePerPhysicalConnection
      :ProviderIntegrationMode=javabean
      :ConnectionFactoryClassName=org.apache.activemq.ActiveMQConnectionFactory
      :QueueConnectionFactoryClassName=org.apache.activemq.ActiveMQConnectionFactory
      :TopicConnectionFactoryClassName=org.apache.activemq.ActiveMQConnectionFactory
      :XAConnectionFactoryClassName=org.apache.activemq.ActiveMQXAConnectionFactory
      :XAQueueConnectionFactoryClassName=org.apache.activemq.ActiveMQXAConnectionFactory
      :XATopicConnectionFactoryClassName=org.apache.activemq.ActiveMQXAConnectionFactory
      :UnifiedDestinationClassName=org.apache.activemq.command.ActiveMQDestination
      :QueueClassName=org.apache.activemq.command.ActiveMQQueue
      :TopicClassName=org.apache.activemq.command.ActiveMQTopic
      :ConnectionFactoryProperties=brokerURL\\\=tcp\\\://127.0.0.1\\\:61616
      :LogLevel=FINE
  myapp#genericra

请注意,上述命令应作为一行执行,并且“:”周围没有空格。就像

asadmin create-resource-adapter-config --property SupportsXA=false:ConnectionFactoryProperties=brokerURL=tcp://127.0.0.1:61616 myapp#genericra

在 DOS 提示符下,您应该只使用一个“/”来进行转义,例如

asadmin create-resource-adapter-config --property SupportsXA=false:ConnectionFactoryProperties=brokerURL=tcp://127.0.0.1:61616 myapp#genericra

将您的应用程序、genericra.rar 和 activemq 依赖项打包到一个 EAR 中。EAR 的结构应该像这样

lib/activemq-core-4.1.1.jar
lib/log4j-1.2.13.jar
lib/commons-logging-1.1.jar
lib/backport-util-concurrent-2.1.jar
lib/activeio-core-3.0.0-incubator.jar
META-INF/application.xml
genericra.rar
mymodules.jar

在 mymodules.jar(我放置 MDB 的地方)中,sun-ejb-jar.xml 应该看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar
  PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 8.1 EJB 2.1//EN"
    "http://www.sun.com/software/appserver/dtds/sun-ejb-jar\_2\_1-1.dtd">
<sun-ejb-jar>
  <enterprise-beans>
    <ejb>
      <ejb-name>TestingMessageDrivenBean</ejb-name>
      <mdb-connection-factory>
        <jndi-name>jms/SimpleQueueConnectionFactory</jndi-name>
      </mdb-connection-factory>
      <mdb-resource-adapter>
        <resource-adapter-mid>myapp#genericra</resource-adapter-mid>
        <activation-config>
          <activation-config-property>
            <activation-config-property-name>DestinationType</activation-config-property-name>
            <activation-config-property-value>javax.jms.Queue</activation-config-property-value>
          </activation-config-property>
          <activation-config-property>
            <activation-config-property-name>DestinationProperties</activation-config-property-name>
            <activation-config-property-value>PhysicalName=Foo.Bar</activation-config-property-value>
          </activation-config-property>
        </activation-config>
      </mdb-resource-adapter>
    </ejb>
  </enterprise-beans>
</sun-ejb-jar>

application.xml 应该看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<application
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
    version="5">
  <description>Example DD</description>
  <display-name>sample app with amq and genericra</display-name>
  <module>
    <ejb>mymodules.jar</ejb>
  </module>
  <module>
    <connector>genericra.rar</connector>
  </module>
</application>

部署 genericra

asadmin deploy --name myapp myapp.ear

创建连接池。在一行中运行以下命令

asadmin create-connector-connection-pool
  --raname myapp#genericra
  --connectiondefinition javax.jms.QueueConnectionFactory
  --transactionsupport LocalTransaction
  ActiveMQQueueConnectionFactoryPool

创建连接工厂管理员对象。在一行中运行以下命令,请注意,“jms/SimpleQueueConnectionFactory”需要与您的 sun-ejb-jar.xml 中的匹配

asadmin create-connector-resource
  --poolname ActiveMQQueueConnectionFactoryPool
  jms/SimpleQueueConnectionFactory

类加载器 / commons-logging+log4j 问题

在上面显示的步骤中,您应该注意一件事情,即 RA、ActiveMQ Classic 和我的 MDB 被部署为一个 EAR。您可以独立部署 genericra,而无需将其放入 EAR,前提是您没有使用 commons-logging 和 log4j(直接或间接)。

在我的应用程序中,使用了 commons-logging,ActiveMQ Classic 也使用了 commons-logging。在 SJSAS 中,连接器类加载器是应用程序类加载器的父类,因此,如果您独立部署 genericra,然后部署您的应用程序,log4j.xml 将永远不会被加载,除非您将应用程序 log4j.xml 与 ActiveMQ Classic jars 一起放置。

使用 Java 标准类加载程序,类加载程序将首先委托父加载程序加载。当应用程序类加载程序查找 LogFactory 类时,它将首先委托给其父类加载程序(即连接器类加载程序)。由于连接器类加载程序已加载 ActiveMQ Classic 及其依赖项(包括 commons-logging),因此 LogFactory 最终将由连接器类加载程序加载。当 commons-logging 尝试初始化 LogFactoryImpl 时,从而触发 log4j 初始化的标准过程,您的应用程序中的 log4j 配置(log4j.xml 或 log4j.properties)将不会被加载(因为 log4j 记录器由连接器类加载程序加载)。

因此,在这种情况下,独立部署 genericra 不是完美的解决方案。

幸运的是,在 Glassfish 论坛上得到了一些建议(感谢 Sivakumar),我找到了一个更好的解决方案,即,将所有内容(包括 genericra 和 activemq)打包到一个 EAR 中。当以这种方式打包时,所有类都将在一个类加载器下加载,好处是,您可以将您的 log4j.xml 放入您的其中一个 jar 中(即,正常方式!)。

但是,您应该注意一个小的细节,独立部署 genericra 和与 EAR 一起打包有一个小的区别。如果您将 RA 与 EAR 一起部署,则需要使用“appName#raName”格式引用 RA。因此,RA 的引用名称是 myapp#genericra(请参阅 create-resource-adapter-config 和 sun-ejb-jar.xml 部分)。

如果您独立部署 RA,则 RA 名称只是 genericra(如 Ramesh 示例中所示)。

本地事务

在上面描述的说明中,使用了本地事务。(SupportsXA=false 和 –transactionsupport LocalTransaction)因为我目前正在使用非 XA 事务,但是,如 Ramesh 所示,XA 也应该可以工作。

配置 genericra

当您创建 resource-adapter-config 时,有两种配置方法。一种方法是使用 JNDI,另一种方法是使用 genericra 的 JavaBean 内省功能。在上面的示例中,我使用 JavaBean 内省功能(因此“ProviderIntegrationMode=javabean”)。有关此的更多详细信息,请查看 genericra 的用户指南。此外,我发现 genericra 网站上提供的示例也是宝贵的资源。

参考资料

Apache、ActiveMQ、Apache ActiveMQ、Apache 羽毛标志和 Apache ActiveMQ 项目标志是 Apache 软件基金会的商标。版权所有 © 2024,Apache 软件基金会。根据 Apache 许可证 2.0 许可。