Error Casting Spring's JndiObjectFactoryBean to ConnectionFactory for Solace-MQ JMS

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

I have a good working XML configuration for Camel Context that uses JNDI with Spring

Later Solace.JndiObjectFactoryBean gets used as connectionFactory

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

I am trying to convert this into a Java class that extends from org.apache.camel.spring.javaconfig.CamelConfiguration. But there is one problem. When I try to set a connection factory on JMS component component.setConnectionFactory(getJndiObjectFactoryBean()); getJndiObjectFactoryBean(), I get a compile time exception :

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

But when I try to cast JndiObjectFactoryBean returned from getJndiObjectFactoryBean explicitly to SolConnectionFactory, I get a runtime error

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) 

I believe do have have requisite jars in the class path. sol-common-x.y.z.jar, sol-jcsmp-x.y.z.jar, sol-jms-x.y.z.jar

回答1:

A JndiObjectFactoryBean cannot be casted into a ConnectionFactory.

There are two options:

  1. Use JndiObjectFactoryBean.getObject() in the JndiObjectFactoryBean that's returned by your getJndiObjectFactoryBean() method.
  2. Get Spring to provide the ConnectionFactory.

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



回答2:

We faced a simular situation when porting a working Spring XML configuration (used by Apache Camel to read from a Weblogic JMS Server queue) to a Spring-Boot favoured Java configuration.

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

Above code did the trick to emulate

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

(Unclear what Spring XML does extra under the cover though, since it's not as simple as setting the jndiFactoryBean on the jmsConfiguration)



回答3:

In case you are using the getObject() approach make sure you call afterPropertiesSet() before you use 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()); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!