Since we're on a major migration process of this website, some component documents here are out of sync right now. In the meantime you may want to look at the early version of the new website
https://camel.apache.org/staging/
We would very much like to receive any feedback on the new site, please join the discussion on the Camel user mailing list.

Why can I not use when/otherwise in a Java Camel route?

When using the Content Based Router in the Java DSL you may have a situation where the compiler will not accept the following when() or otherwise() statement.

Quick tip

Use .endChoice() to return "back" to the Content Based Router

For example as shown in the route below where we use the Load Balancer inside the Content Based Router in the first when:

Code will not compile
from("direct:start")
    .choice()
        .when(body().contains("Camel"))
            .loadBalance().roundRobin().to("mock:foo").to("mock:bar")
        .otherwise()
            .to("mock:result");

Well the first issue is that the Load Balancer uses the additional routing to know what to use in the load balancing. In this example that would be the:

.to("mock:foo").to("mock:bar")

To indicate when the balancing stops, you should use .end() to denote the end. So the route is updates as follows:

Code will still not compile
from("direct:start")
    .choice()
        .when(body().contains("Camel"))
            .loadBalance().roundRobin().to("mock:foo").to("mock:bar").end()
        .otherwise()
            .to("mock:result");

But the code will still not compile. The reason is we have stretched how far we can take the good old Java language in terms of DSL. In a more modern language such as Scala or Groovy you would be able to let it be stack based, so the .end() will pop the last type of the stack, and you would return back to the scope of the Content Based Router. However that's not easily doable in Java. So we need to help Java a bit, which you do by using .endChoice(), which tells Camel to "pop the stack" and return back to the scope of the Content Based Router.

Code compiles
from("direct:start")
    .choice()
        .when(body().contains("Camel"))
            .loadBalance().roundRobin().to("mock:foo").to("mock:bar").endChoice()
        .otherwise()
            .to("mock:result");

You only need to use .endChoice() when using certain EIPs which often have additional methods to configure or as part of the EIP itself. For example the Splitter EIP has a sub-route which denotes the routing of each splitted message. You would also have to use .endChoice() to indicate the end of the sub-route and to return back to the Content Based Router. Note .endChoice() is available as of Camel 2.7.

Still problems

If there is still problems, then you can split your route into multiple routes, and link them together using the Direct component.
There can be some combinations of EIPs that can hit limits in how far we can take the fluent builder DSL with generics you can do in Java programming language (1.7 and below).

© 2004-2015 The Apache Software Foundation.
Apache Camel, Camel, Apache, the Apache feather logo, and the Apache Camel project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.
Graphic Design By Hiram