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 网站上提供的示例也是宝贵的资源。