【问题标题】:MDB under GlassFish listening to remote JMS Queue (MQ via GenericJMSRA)GlassFish 下的 MDB 监听远程 JMS 队列(MQ via GenericJMSRA)
【发布时间】:2014-10-20 21:33:52
【问题描述】:

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

当我尝试使用 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 { ... }

我收到此错误(从堆栈跟踪中提取的最少内容):

java.lang.RuntimeException: EJB Container initialization error
    at org.glassfish.ejb.startup.EjbApplication.loadContainers(EjbApplication.java:242)
Caused by: java.lang.Exception
    at com.sun.enterprise.connectors.inbound.ConnectorMessageBeanClient.setup(ConnectorMessageBeanClient.java:233)
Caused by: javax.resource.spi.InvalidPropertyException: MyFactory
    at com.sun.genericra.util.ExceptionUtils.newInvalidPropertyException(ExceptionUtils.java:42)
Caused by: javax.naming.NameNotFoundException: MyFactory
    at com.sun.jndi.fscontext.RefFSContext.getObjectFromBindings(RefFSContext.java:400)

如果我使用 .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 名称时,我得到与上面相同的堆栈跟踪,但指的是“MyQueue”。

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

QueueConnectionFactory qcf = (QueueConnectionFactory) ctx.lookup("jms/MyFactory");
Queue asyncQueue = (Queue) ctx.lookup("jms/MyQueue");

有人可以提供有关为什么会发生这种情况的见解吗?我想在代码的任何地方都使用 JNDI 名称,例如“jms/MyQueue”——包括 MDB 定义。

这是我的 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>
  • GlassFish 3.1.2.9
  • WebSphere MQ 7
  • genericra 2.0.1
  • Java 1.7/JEE 6/EJB 3.1

【问题讨论】:

    标签: jms java-ee-6 glassfish-3 ibm-mq message-driven-bean


    【解决方案1】:

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

    值得注意的是,WMQ 有它自己的资源适配器——这里没有必要使用通用的。可能是探索的途径?

    【讨论】:

    • 感谢您指出这一点。可悲的是,我们一定会使用泛型。
    【解决方案2】:

    到目前为止,我们设法找到了解决方案。使用 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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 2015-12-03
      • 2020-09-03
      • 2020-01-01
      • 1970-01-01
      • 2010-12-26
      相关资源
      最近更新 更多