I have a Spring Boot + Apache Camel project that works brilliantly. I just added a new bean though where I wanted to have its implementation be profile-specific. I created Spring tests to verify it, and it works as expected, but when I run the server I get the following stack trace:
Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: MyFancyBean at org.apache.camel.component.bean.RegistryBean.getBean(RegistryBean.java:94) at org.apache.camel.model.language.MethodCallExpression.createExpression(MethodCallExpression.java:196) at org.apache.camel.model.language.MethodCallExpression.createPredicate(MethodCallExpression.java:210) at org.apache.camel.model.language.ExpressionDefinition.createPredicate(ExpressionDefinition.java:148) at org.apache.camel.model.ValidateDefinition.createProcessor(ValidateDefinition.java:63) at org.apache.camel.model.ValidateDefinition.createProcessor(ValidateDefinition.java:35) at org.apache.camel.model.ProcessorDefinition.makeProcessorImpl(ProcessorDefinition.java:545) at org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:506) at org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:222) at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1068)
I have an interface and two implementations:
public interface MyFancyBean { ... }
public class FooFancyBean implements MyFancyBean { ... }
public class NonFooFancyBean implements MyFancyBean { ... }
Depending on profile, the correct bean is read instantiated:
@Configuration
public class AppConfig {
@Bean
@Profile("foo")
MyFancyBean fooBean() {
return new FooFancyBean();
}
@Bean
@Profile("!foo")
MyFancyBean nonFooBean() {
return new NonFooFancyBean();
}
}
I've verified this works a couple of ways. First, a couple tests:
@ActiveProfiles("anything-but-foo")
@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan(basePackages = {"com.example", "com.jtv.spring.boot"})
@EnableAutoConfiguration
@Component
public class NonFooBean_SpringTest {
@Autowired
private MyFancyBean bean;
@Test
// ... here "bean" is instantiated as "NonFooFancyBean"
So the test works.
Further, when I start my app, depending on profile the correct bean in my @Configuration class above is called.
But Camel is still angry and says "NoSuchBeanException" on startup.
FWIW, here's how I'm referencing the bean:
@Component
public class MyCamelRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
// [...]
from("direct:processStuff").
validate().method("MyFancyBean").
process("MyProcessor");
}
}
How do I get Camel to honor this config?
Whoooo... Y'all get to be my rubber duck today. I just autowired it. (This doesn't work for my processor, which is why it didn't occur to me initially.)
@Component
public class MyCamelRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
// [...]
@Autowired MyFancyBean myFancyBean;
from("direct:processStuff").
validate().method(myFancyBean).
process("MyProcessor");
}
}