tomcat - 如果在多个tomcat context.xml中定义了qmanager jndi,则MQ JNDI异常

标签 tomcat jms jndi ibm-mq spring-jms

我在同一个 tomcat jvm 中部署了 2 个应用程序。每个应用程序都有自己的 context.xml: - app1.xml - app2.xml 在每个 app*.xml 中,我都定义了 MQ jndi 资源:

<!-- JMS configuration FOR MQSeries - The connection factory -->
 <Resource
      name="jms/JMSQueueConnectionFactory"
      auth="Container"
      type="com.ibm.mq.jms.MQQueueConnectionFactory"
      factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
      description="JMS Queue Connection Factory for sending messages"
      CCDTURL="file:///apps/mqm_opt/creds/AMQCLCHL_XA.TAB"
      QMGR="***Example***QM01***Example***" UCP="Y"/>

我的任何 war 中都没有 MQ 或 jms jar 。它们在 MQ 客户端安装上。然后我使用 catalina.properties 的 shared.loader 在类路径中添加:

shared.loader=${catalina.home}/shared/*.jar,/opt/mqm/java/lib/*.jar

每个应用程序单独部署时都很好。但是当它们一起部署在同一个 jvm 中时,我在启动其中一个应用程序时得到一个空指针:

Jul 29, 2015 6:15:14 PM org.apache.naming.NamingContext lookup
WARNING: Unexpected exception resolving reference
java.lang.NullPointerException
        at com.ibm.msg.client.jms.internal.JmsFactoryFactoryImpl.getInstance(JmsFactoryFactoryImpl.java:169)
        at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.setProviderFactory(JmsConnectionFactoryImpl.java:176)
        at com.ibm.mq.jms.MQConnectionFactory.<init>(MQConnectionFactory.java:286)
        at com.ibm.mq.jms.MQQueueConnectionFactory.<init>(MQQueueConnectionFactory.java:76)
        at com.ibm.mq.jms.MQQueueConnectionFactoryFactory.getObjectInstance(MQQueueConnectionFactoryFactory.java:73)
        at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
        at javax.naming.spi.NamingManager.getObjectInstance(Unknown Source)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:830)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:830)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:830)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:167)
        at org.apache.naming.SelectorContext.lookup(SelectorContext.java:156)
        at javax.naming.InitialContext.lookup(Unknown Source)
        at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
        at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
        at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
        at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
        at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201)
        at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)

所以 app1 工作正常,但 app2 失败并出现上述异常。我通常注意到这种错误是在我们遇到类加载问题时出现的。但在这种情况下,我无法弄清楚问题出在哪里。任何线索都会有所帮助。

编辑:经过一些测试后我发现,如果 tomcat 首先加载 app1,那么这两个应用程序都可以正常工作。但是如果它选择 app2 那么就会有问题。似乎 app2 正在使用错误的类加载器加载 MQ 类。不知道为什么。我检查了 war 。它不包含 MQ 类。

最佳答案

基于 http://tomcat.apache.org/tomcat-8.0-doc/jndi-resources-howto.html#Using_resources 中的注释我会建议 TomCat 中的资源 应该沿着这些路线。

<Resource name="jms/MyJMSCF" auth="Container"
          type="com.ibm.mq.jms.MQConnectionFactory"
          factory="org.apache.naming.factory.BeanFactory"
          hostName="my.host.name"
          transportType="1"/>  <!-- 1 means client mode -->

MQConnectionFactory 应该是兼容的 bean 样式对象;有很多配置选项——完整的 JavaDoc 是 http://www-01.ibm.com/support/knowledgecenter/api/content/SSFKSJ_8.0.0/com.ibm.mq.javadoc.doc/WMQJMSClasses/com/ibm/mq/jms/MQConnectionFactory.html

com.ibm.mq.jms.MQQueueConnectionFactoryFactory 对象仅供 JNDI 使用,以通过 javax.naming.Referencable 接口(interface)重新扩充对象存储。

关于tomcat - 如果在多个tomcat context.xml中定义了qmanager jndi,则MQ JNDI异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31711066/

相关文章:

linux - 从 linux 服务器到 windows 服务器的 Jenkins 部署

java - 如何发出 JMS 同步请求

java - 如何将 JMS 队列视为临时存储?

grails - 由于 JNDI 查找,无法在 Grails 集成测试中初始化服务

java - 无法将类型 [JmsManagedConnectionFactoryImpl] 的值转换为所需类型 [javax.jms.ConnectionFactory]

java - JBoss:在 JBoss EAP 6 中将值绑定(bind)到 JNDI 类似于 JNDIBindingServiceMgr

java - index.html 404 - 在 tomcat 服务器中找不到

tomcat - 嵌入在 Tomcat 中的 OSGi 中的 ClassCastException

java - 服务器如何了解来自特定区域的传入请求以使用语言环境语言提供网页

java - SpringIntegration 在不处理的情况下从队列中删除消息