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

@PropertyInject is broken for Spring projects using CamelTestContextBootstrapper

    XMLWordPrintableJSON

    Details

    • Estimated Complexity:
      Unknown

      Description

      I'm trying to override properties in a Camel Spring project. In my production code, I have
      a field injected with

      @Component
      public class MyRouteBuilder extends SpringRouteBuilder {

      @PropertyInject("MY_PROPERTY ")
      private String myProperty;

      }

      I normally load the value from a properties file using a BridgePropertyPlaceholderConfigurer.

      In one of my tests, I'd like to replace the property. My test looks as follows:

      @RunWith(CamelSpringRunner.class)
      @BootstrapWith(CamelTestContextBootstrapper.class)
      @ContextConfiguration(locations =

      { "classpath:META-INF/spring/my-properties.xml" }

      )
      @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
      @UseAdviceWith
      public class CitizenLookupPatientByOIDRouteTest {
      @Test
      public void test()

      { ... }

      @UseOverridePropertiesWithPropertiesComponent
      public static Properties overrideProperties()

      { Properties overrides = new Properties(); overrides.setProperty("MY_PROPERTY", "some-value"); return overrides; }

      }

      What I am seeing is that the injected field gets the value from the properties file, rather
      than the overridden value. Debugging this, I see that the field injection happens during Spring
      bean postprocessing, which is before the overrideProperties method is called.

      parseUri:190, PropertiesComponent (org.apache.camel.component.properties)
      parseUri:178, PropertiesComponent (org.apache.camel.component.properties)
      resolvePropertyPlaceholders:2547, DefaultCamelContext (org.apache.camel.impl)
      getInjectionPropertyValue:276, CamelPostProcessorHelper (org.apache.camel.impl)
      injectFieldProperty:214, DefaultCamelBeanPostProcessor (org.apache.camel.impl)
      doWith:174, DefaultCamelBeanPostProcessor$1 (org.apache.camel.impl)
      doWithFields:74, ReflectionHelper (org.apache.camel.util)
      injectFields:170, DefaultCamelBeanPostProcessor (org.apache.camel.impl)
      postProcessBeforeInitialization:83, DefaultCamelBeanPostProcessor (org.apache.camel.impl)
      postProcessBeforeInitialization:154, CamelBeanPostProcessor (org.apache.camel.spring)
      applyBeanPostProcessorsBeforeInitialization:419, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
      initializeBean:1737, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
      doCreateBean:576, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
      createBean:498, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
      lambda$doGetBean$0:320, AbstractBeanFactory (org.springframework.beans.factory.support)
      getObject:-1, 1286771084 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$40)
      getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
      doGetBean:318, AbstractBeanFactory (org.springframework.beans.factory.support)
      getBean:199, AbstractBeanFactory (org.springframework.beans.factory.support)
      preInstantiateSingletons:846, DefaultListableBeanFactory (org.springframework.beans.factory.support)
      finishBeanFactoryInitialization:863, AbstractApplicationContext (org.springframework.context.support)
      refresh:546, AbstractApplicationContext (org.springframework.context.support)
      loadContext:152, CamelSpringTestContextLoader (org.apache.camel.test.spring)
      loadContext:89, CamelSpringTestContextLoader (org.apache.camel.test.spring)
      loadContextInternal:99, DefaultCacheAwareContextLoaderDelegate (org.springframework.test.context.cache)
      loadContext:117, DefaultCacheAwareContextLoaderDelegate (org.springframework.test.context.cache)
      getApplicationContext:108, DefaultTestContext (org.springframework.test.context.support)
      injectDependencies:118, DependencyInjectionTestExecutionListener (org.springframework.test.context.support)
      prepareTestInstance:83, DependencyInjectionTestExecutionListener (org.springframework.test.context.support)
      prepareTestInstance:246, TestContextManager (org.springframework.test.context)
      createTest:227, SpringJUnit4ClassRunner (org.springframework.test.context.junit4)

      The code causing the injection in CamelSpringContextLoader is this https://github.com/apache/camel/blob/camel-2.23.1/components/camel-test-spring/src/main/java/org/apache/camel/test/spring/CamelSpringTestContextLoader.java#L152.
      A few lines below, the properties override code is called.

      The issue here is that Spring is responsible for injecting the property value into the @PropertyInject field, but CamelSpringTestContextLoader first loads the Spring context, thus causing field injection, and then sets the property overrides.

      I'll put up a PR with a proposal for a fix shortly.

        Attachments

          Activity

            People

            • Assignee:
              acosentino Andrea Cosentino
              Reporter:
              srdo Stig Rohde Døssing
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 40m
                40m