Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-11431

Spring beans with autowired constructors

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 2.19.0
    • 2.20.0
    • camel-core, camel-spring
    • 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

      Attachments

        Activity

          People

            davsclaus Claus Ibsen
            kszafran Krzysztof SzafraƄski
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: