首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mule:使用容器自己的jndiInitialFactory

Mule:使用容器自己的jndiInitialFactory
EN

Stack Overflow用户
提问于 2012-09-17 14:43:46
回答 1查看 2.2K关注 0票数 2

考虑下面的mule配置,并将mule嵌入到Web (Java )应用程序中:

代码语言:javascript
复制
<jms:connector
        name="jmsConnector"
        connectionFactory-ref="jmsConnectionFactory"> <!-- From spring -->
        <!-- JNDI Name Resover here? -->
</jms:connector>
<flow name="mainTestFlow">
    <jms:inbound-endpoint connector-ref="jmsConnector" 
        queue="jms/MessageQueue" />
    <logger level="INFO" category="mule.message.logging" message="Message arrived." />
</flow>

jmsConnectionFactory引用了在Spring中定义的jmsConnectionFactory,它来自:

代码语言:javascript
复制
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jms/QueueConnectionFactory" />
</bean>

队列连接工厂已经过测试并正在工作。

jms/MessageQueue队列名引用了在web应用程序web.xml文件中定义的资源-ref。此JNDI引用在容器级别绑定到由应用服务器管理的javax.jms.Queue,并连接到适当的消息传递服务器(本例中为ActiveMQ)。

但是,Mule并不将queue=""属性作为JNDI目标,而是作为队列名称本身。因此,当初始化上面的代码时,它实际上在ActiveMQ中创建了一个名为"jms/MessageQueue“的新队列。我真正想要的是,它从Web应用程序描述符中的JNDI引用中正确地检索到队列。

好的,您可以说,我所要做的就是在JMS中配置一个JNDI,并向它添加jndiDestinations="true"forceJndiDestinations="true"属性。

这是可以接受的:

代码语言:javascript
复制
<jms:default-jndi-name-resolver 
    jndiProviderUrl="tcp://localhost:1099"
    jndiInitialFactory="???"/>

真正的问题是,我不想在jndiInitialFactory,中放置真正的初始上下文工厂类名,因为它属于特定于容器的定义。但是,我的应用程序有时被部署到JBoss 4.2.3中,有时被部署到WebSphere 7中。由于我们的开发过程,拥有2个配置和2个EAR包不是一种选择。

无论如何,是否可以告诉Mule-ESB假设当前容器(因为它处于嵌入式模式)作为默认的用于查找的JNDI初始工厂,或者提供一个“通用”的JNDI初始工厂来识别容器的JNDI环境?这不应该是个问题,因为一个web应用程序可以引用它的容器JNDI环境,而不需要额外的(甚至可见的)配置。

如果不可能,我是否可以让jms:inbound-endpoint引用在Spring中定义的javax.jms.Queue,就像jms:connector对所做的那样?这实际上是相当优雅和干净的,因为Mule是春天友好的。

提前谢谢大家!

溶液

经过深思熟虑,我终于通过创建一个连接到spring设施的定制JndiNameResolver (例如JndiTemplate)来解决我的问题。这远非最好的解决方案,但我发现,这将是对Mule和Spring的内在复杂性的干扰最少的解决方案。

这就是说,下面是类: package com.filcobra.mule;

代码语言:javascript
复制
import javax.naming.NamingException;

import org.mule.transport.jms.jndi.AbstractJndiNameResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jndi.JndiObjectLocator;
import org.springframework.jndi.JndiTemplate;

public class SpringJndiNameResolver extends AbstractJndiNameResolver implements InitializingBean {
    private static Logger logger = LoggerFactory.getLogger(SpringJndiNameResolver.class);
    private JndiTemplate jndiTemplate;

    @Override
    public void afterPropertiesSet() throws Exception {
        if (jndiTemplate == null) {
            jndiTemplate = new JndiTemplate();
        }
    }

    @Override
    public Object lookup(String name) throws NamingException {
        Object object = null;
        if (name != null) {
            logger.debug("Looking up name "+name);
            object = jndiTemplate.lookup(name);
            logger.debug("Object "+object+" found for name "+name);
        }
        return object;
    }

    public JndiTemplate getJndiTemplate() {
        return jndiTemplate;
    }

    public void setJndiTemplate(JndiTemplate jndiTemplate) {
        this.jndiTemplate = jndiTemplate;
    }
}

这样,配置就回到了通常的状态:

代码语言:javascript
复制
<spring:bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate" />

<jms:connector
        name="jmsConnector"
        connectionFactoryJndiName="java:comp/env/jms/MyConnectionFactory" <!-- from Resource-Ref -->
        jndiDestinations="true"
        forceJndiDestinations="true"
        specification="1.1" >

    <jms:custom-jndi-name-resolver class="com.filcobra.mule.SpringJndiNameResolver">
        <spring:property name="jndiTemplate" ref="jndiTemplate"/>
    </jms:custom-jndi-name-resolver>    
</jms:connector>

有了这一点,我终于能够不将Mule ESB安装绑定到特定的JMS供应商/实现上。实际上,JMS (队列和工厂)配置都由应用服务器负责。

然而,有一件事仍然很奇怪。我希望JMS端点也使用我的Jndi Name Resolver来从资源引用(或其JNDI名称)中查找队列,就像对Connection一样。不管怎么说都没用。最后,我将队列名称放在JMS服务器中创建的队列名称中,从而解决了这一问题:

代码语言:javascript
复制
<flow name="mainTestFlow">
    <jms:inbound-endpoint connector-ref="jmsConnector" queue="queue/myQueue"/> <!-- Queue Name, not JNDI Name -->

起作用了。因此,我假设JMS连接器没有尝试查找队列,而是简单地使用连接工厂(查找或不查找)直接访问JMS服务器。

致以问候!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-17 20:22:48

我在源代码中看到了问题:基本上,如果您提供外部创建的连接工厂,jndiDestinationsforceJndiDestinations将强制设置为false

最近我还没有为您的问题提供一个通用的解决方案,这确实是最好的解决方案。

我将尝试的是子类org.mule.transport.jms.Jms11Support,在其中注入我的Spring查找队列,在内部重新连接它以使用这些队列,最后将它注入Mule JMS连接器本身。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12461714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档