【问题标题】:Error Casting Spring's JndiObjectFactoryBean to ConnectionFactory for Solace-MQ JMS将 Spring 的 JndiObjectFactoryBean 转换为 Solace-MQ JMS 的 ConnectionFactory 时出错
【发布时间】:2016-05-19 19:59:01
【问题描述】:

我有一个使用 JNDI 和 Spring 的 Camel Context 的良好工作 XML 配置

后来 Solace.JndiObjectFactoryBean 被用作 connectionFactory

<bean id="Solace.JmsComponent" class="  on">
    <property name="connectionFactory" ref="Solace.JndiObjectFactoryBean" />
    <property name="destinationResolver" ref="Solace.JndiDestinationResolver" />
</bean>

我正在尝试将其转换为从 org.apache.camel.spring.javaconfig.CamelConfiguration 扩展的 Java 类。但是有一个问题。当我尝试在 JMS 组件上设置连接工厂时 component.setConnectionFactory(getJndiObjectFactoryBean()); getJndiObjectFactoryBean(), 我得到一个编译时异常:

The method setConnectionFactory(ConnectionFactory) in the type JmsComponent 
is not applicable for the arguments (JndiObjectFactoryBean)

但是当我尝试将从 getJndiObjectFactoryBean 返回的 JndiObjectFactoryBean 显式转换为 SolConnectionFactory 时,出现运行时错误

016-02-05 17:39:09,234|[localhost-startStop-1]|[]|[]|[ERROR] web.context.ContextLoader [line:307] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getJMSConfiguration' defined in class path resource [com//camel
/CamelRoutesConfig.class]: Instantiation of bean failed; nested exception is org
.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.apache.camel.component.jms.JmsConfiguration com.camel.CamelRoutesConfig.getJMSConfiguration()] threw exception; nested exception is java.lang.ClassCastException: org.springframework.jndi.JndiObjectFactoryBean$$EnhancerByCG
LIB$$18b94f95 cannot be cast to com.solacesystems.jms.SolConnectionFactory
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsi
ngFactoryMethod(ConstructorResolver.java:581)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1029)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
.createBeanInstance(AbstractAutowireCapableBeanFactory.java:925)

我相信在类路径中确实有必要的 jar。 sol-common-x.y.z.jar, sol-jcsmp-x.y.z.jar, sol-jms-x.y.z.jar

【问题讨论】:

    标签: jms apache-camel spring-jms solace solace-mq


    【解决方案1】:

    JndiObjectFactoryBean 不能转换为 ConnectionFactory

    有两种选择:

    1. 在您的getJndiObjectFactoryBean() 方法返回的JndiObjectFactoryBean 中使用JndiObjectFactoryBean.getObject()
    2. 让 Spring 提供ConnectionFactory

      ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); ConnectionFactory connectionFactory = (ConnectionFactory) context.getBean("Solace.JndiObjectFactoryBean");

    【讨论】:

    • 嗨,Russell,虽然我使用了 getObject(),但我无法让它工作。您能否提供任何示例代码。
    【解决方案2】:

    在将工作的 Spring XML 配置(Apache Camel 用于从 Weblogic JMS 服务器队列中读取)移植到 Spring-Boot 支持的 Java 配置时,我们遇到了类似的情况。

    jmsConfiguration.setConnectionFactory( (javax.jms.ConnectionFactory)getJndiFactoryBean().getObject());
    

    上面的代码可以模拟

    <bean id="jmsConfiguration" class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="jndiFactoryBean"/>
        <property name="destinationResolver" ref="jndiDestinationResolver"/>
    </bean>
    

    (虽然不清楚 Spring XML 在幕后做了什么,因为它不像在 jmsConfiguration 上设置 jndiFactoryBean 那样简单)

    【讨论】:

      【解决方案3】:

      如果您使用 getObject() 方法,请确保在使用 getObject() 之前调用 afterPropertiesSet()

      org.springframework.jndi.JndiObjectFactoryBean cf = new org.springframework.jndi.JndiObjectFactoryBean();
      JndiTemplate jndiTemplate = new org.springframework.jndi.JndiTemplate();
      Properties environment = new Properties();
      environment.setProperty("java.naming.factory.initial", "com.xxx"); //initial context
      environment.setProperty("java.naming.provider.url", "xxx://xxx"); //url
      jndiTemplate.setEnvironment(environment);
      cf.setJndiTemplate(jndiTemplate);
      cf.setJndiName("XXX");
      //System.out.println(cf.getObject()); //null
      cf.afterPropertiesSet();
      //System.out.println(cf.getObject()); //now has the value
      
      org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter adapter = new org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter();
      adapter.setTargetConnectionFactory((ConnectionFactory) cf.getObject());
      

      【讨论】:

        猜你喜欢
        • 2016-08-16
        • 2021-01-08
        • 2018-04-07
        • 2012-08-27
        • 2012-02-12
        • 1970-01-01
        • 2020-01-07
        • 2013-01-09
        • 2020-09-29
        相关资源
        最近更新 更多