Details
-
Improvement
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
2.19.0
-
None
-
Unknown
Description
I have stumbled upon an issue when using Spring beans in routes using the following syntax:
from(...).bean(MySpringBean.class)
I haven't found a relevant entry in Camel's documentation whether that is a valid use in conjunction with Spring, but it actually works... most of the time. It does not work when MySpringBean uses constructor injection (it is OK with field injection).
I have traced the issue to this part of org.apache.camel.model.BeanDefinition:
// create a bean if there is a default public no-arg constructor if (isCacheBean() && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) { bean = CamelContextHelper.newInstance(routeContext.getCamelContext(), clazz); ObjectHelper.notNull(bean, "bean", this); }
When constructor injection is used the above condition does not hold, and instead of having beanHolder of type ConstantBeanHolder we end up with ConstantStaticTypeBeanHolder, whose getBean() method always returns null.
In effect I'm getting this stacktrace:
java.lang.NullPointerException: null at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:472) at org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:291) at org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:264) at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:178) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97) at org.apache.camel.processor.aggregate.AggregateProcessor$1.run(AggregateProcessor.java:763) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.camel.util.concurrent.SynchronousExecutorService.execute(SynchronousExecutorService.java:62) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at org.apache.camel.processor.aggregate.AggregateProcessor.onSubmitCompletion(AggregateProcessor.java:755) at org.apache.camel.processor.aggregate.AggregateProcessor.doProcess(AggregateProcessor.java:355) at org.apache.camel.processor.aggregate.AggregateProcessor.process(AggregateProcessor.java:268) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:695) at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:623) at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:247) at org.apache.camel.processor.Splitter.process(Splitter.java:114) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62) at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:117) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:695) at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:623) at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:247) at org.apache.camel.processor.Splitter.process(Splitter.java:114) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62) at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62) at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:117) at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77) at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198) at org.apache.camel.processor.Pipeline.process(Pipeline.java:120) at org.apache.camel.processor.Pipeline.process(Pipeline.java:83) at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109) at org.apache.camel.processor.Pipeline.process(Pipeline.java:63) at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:173) at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:451) at org.apache.camel.component.file.remote.RemoteFileConsumer.processExchange(RemoteFileConsumer.java:137) at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:218) at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:182) at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:748)
So either:
- .bean(MySpringBean.class) is not a valid usage for Spring beans
- such usage should be explicitly limited to Spring beans with no-arg constructors (and an explanatory exception should be thrown otherwise)
- BeanDefinition should not assume that the Injector is unable to instantiate beans without no-args constructors, because some (like SpringInjector) are able to do that