问题
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:
- Use
JndiObjectFactoryBean.getObject()
in theJndiObjectFactoryBean
that's returned by yourgetJndiObjectFactoryBean()
method. 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());
来源:https://stackoverflow.com/questions/35298732/error-casting-springs-jndiobjectfactorybean-to-connectionfactory-for-solace-mq