Hi everyone, recently we had a typo in one of our route definitions that resulted in a duplicate route ID but no error message and unexpected replacement of an existing route. This is the bootstrap order found in some Camel examples:
CamelContext context = new DefaultCamelContext(); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:foo").routeId("foo").stop(); } }); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:bar").routeId("foo").stop(); } }); context.start(); You'll get a duplicate route ID exception. If instead you start the context before you add the routes, you won't get an exception and the "direct:bar" route will simply replace the "direct:foo" route, as they have the same ID. This is consistent with the Javadoc of the API and probably a useful feature. However if like in our case you use camel-spring-boot, the RouteCollector will add routes after the Camel context has started. You won't detect duplicate route IDs but instead any later discovered RouteBuilder will override existing routes with the same ID. I'm no Spring expert but it seems the CamelContext start should be deferred in the Spring Boot integration code: The CamelBeanPostProcessor factory method triggers CamelContext creation (due to injection in the factory method) and starts SpringCamelContext during the BeanPostProcessor initialization phase in Spring (InitializingBean). Any necessary transitive bean creation will therefore also happen in that phase. We see a lot of Spring warnings (actually INFO, but it probably should be WARN) that some BeanPostProcessors had to be skipped, because we are starting inside a BeanPostProcessor call. One of those is for example our custom BeanPostProcessor which adds discovered EventNotifiers to the CamelContext, something the Spring Boot integration doesn't provide yet. We think this has to be done before the CamelContext is started, after looking at the ManagementStrategy code. Hence you can't do this with the CamelConfiguration interface of camel-spring-boot, the context has already been started at that point. Our solution was a simple integration class for Spring Boot that starts the context later, after configuration. Would be great to know if we are missing something, although we'll probably stay on 2.14 anyway for this project due end of March. Cheers, Christian