GlassFish下的MDB侦听远程JMS队列(通过GenericJMSRA进行MQ)

GlassFish下的MDB侦听远程JMS队列(通过GenericJMSRA进行MQ),jms,java-ee-6,glassfish-3,ibm-mq,message-driven-bean,Jms,Java Ee 6,Glassfish 3,Ibm Mq,Message Driven Bean,我正在尝试在Glassfish 3.1.2中配置MDB以侦听远程JMS队列(通过GenericJMSRA 2.0.1配置MQ 7) 当我尝试使用JNDI名称像这样定义我的MDB时 @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigPro

我正在尝试在Glassfish 3.1.2中配置MDB以侦听远程JMS队列(通过GenericJMSRA 2.0.1配置MQ 7)

当我尝试使用JNDI名称像这样定义我的MDB时

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "jms/MyQueue"),
    @ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "jms/MyFactory") })
@TransactionManagement(TransactionManagementType.BEAN)
public class SimpleMdb implements MessageListener { ... }
我收到此错误(从stacktrace中提取的最小值):

如果我使用.bindings文件和资源适配器定义中定义的工厂和队列的名称,如下图所示,它就可以正常工作

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "SOME.REALLY.UGLY.LONG.NAME"),
    @ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "THE_NAME_OF_THE_FACTORY") })
@TransactionManagement(TransactionManagementType.BEAN)
public class SimpleMdb implements MessageListener { ... }
当我只将工厂的JNDI名称替换为“丑陋”名称时,我得到了与上面相同的stacktrace,但指的是“MyQueue”

同时,我对.bindings文件的设置、domain.xml中的资源适配器定义(通过工具插入)以及ejb/servlet中的队列使用似乎都很好。 我可以以通常所需的方式使用队列及其连接工厂-这很好:

QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("jms/MyFactory");
Queue asyncQueue = (Queue) ctx.lookup("jms/MyQueue");
有人能提供关于为什么会发生这种情况的见解吗?我希望在代码中的任何地方都使用JNDI名称,如“jms/MyQueue”,包括MDB定义

以下是my domain.xml的相关部分:

<resource-adapter-config thread-pool-ids="genericra-thread-pool" resource-adapter-name="genericra">
  <property name="SupportsXA" value="false"></property>
  <property name="ProviderIntegrationMode" value="jndi"></property>
  <property name="RMPolicy" value="OnePerPhysicalConnection"></property>
  <property name="LogLevel" value="FINEST"></property>
  <property name="JndiProperties" value="..."></property>
</resource-adapter-config>
<connector-connection-pool name="genericra-pool-1" resource-adapter-name="genericra" is-connection-validation-required="true" connection-definition-name="javax.jms.QueueConnectionFactory" fail-all-connections="true" transaction-support="NoTransaction">
  <property name="ConnectionFactoryJndiName" value="THE_NAME_OF_THE_FACTORY"></property>
</connector-connection-pool>
<connector-resource pool-name="genericra-pool-1" jndi-name="jms/MyFactory"></connector-resource>
<admin-object-resource res-adapter="genericra" res-type="javax.jms.Queue" jndi-name="jms/MyQueue">
  <property name="DestinationJndiName" value="SOME.REALLY.UGLY.LONG.NAME"></property>
  <property name="Name" value="jms/MyQueue"></property>
</admin-object-resource>

  • 玻璃鱼3.1.2.9
  • WebSphere MQ 7
  • genericra 2.0.1
  • Java1.7/JEE6/EJB3.1

一般假设是JNDI中缺少一些东西-JNDI是如何填充的?看起来这是基于堆栈跟踪和您提到的.bindings文件的文件系统上下文


同样值得注意的是,WMQ有自己的资源适配器——这里不需要使用通用适配器。可能是一条探索的途径?

现在我们设法找到了一个解决方案。使用genericra,无法将MDB重定向到genericra提供给资源的JNDI名称。相反,MDB必须引用由.bindings文件定义的队列名称(在左侧,而不是右侧的远程名称)。 幸运的是,我们能够根据需要调整.bindings文件

现在,我们可以在genericra配置中使用给定给资源的JNDI名称,以便在代码中“正常”使用,如下所示:

QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("jms/MyFactory");
Queue asyncQueue = (Queue) ctx.lookup("jms/MyQueue");
但是MDB必须使用.bindings中给出的名称:

@ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "QUEUE_NAME_IN_BINDINGS")

谢谢你指出这一点。遗憾的是,我们必须使用genericra。
@ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "QUEUE_NAME_IN_BINDINGS")