Ошибка приведения Spring JndiObjectFactoryBean к ConnectionFactory для Solace-MQ JMS

У меня есть хорошая рабочая конфигурация XML для Camel Context, которая использует JNDI с Spring.

Позже Solace.JndiObjectFactoryBean используется как connectionFactory.

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

Я пытаюсь преобразовать это в класс Java, который расширяется от org.apache.camel.spring.javaconfig.CamelConfiguration. Но есть одна проблема. Когда я пытаюсь установить фабрику соединений в компоненте JMS component.setConnectionFactory(getJndiObjectFactoryBean()); getJndiObjectFactoryBean(), я получаю исключение времени компиляции:

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

Но когда я пытаюсь привести JndiObjectFactoryBean, возвращенный из getJndiObjectFactoryBean, явно к 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)

Я считаю, что на пути к классу есть необходимые банки. sol-common-xyzjar, sol-jcsmp-xyzjar, sol-jms-xyzjar


person user721025    schedule 09.02.2016    source источник


Ответы (3)


JndiObjectFactoryBean нельзя превратить в ConnectionFactory.

Есть два варианта:

  1. Используйте JndiObjectFactoryBean.getObject() в JndiObjectFactoryBean, возвращаемом вашим методом getJndiObjectFactoryBean().
  2. Получите Spring, чтобы предоставить файл ConnectionFactory.

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

person Russell Sim    schedule 10.02.2016
comment
Привет, Рассел, я не могу заставить его работать, хотя я использовал getObject(). Не могли бы вы предоставить любой пример кода. - person amu61; 16.10.2018

Мы столкнулись с аналогичной ситуацией при переносе рабочей конфигурации Spring XML (используемой Apache Camel для чтения из очереди Weblogic JMS Server) в предпочитаемую 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 делает дополнительно под прикрытием, поскольку это не так просто, как установить jndiFactoryBean на jmsConfiguration)

person dmitri    schedule 14.09.2016

Если вы используете подход getObject(), убедитесь, что вы вызываете afterPropertiesSet(), прежде чем использовать getObject().

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());
person ObviousChild    schedule 27.10.2016