[[WhycanInotusewhenorotherwiseinaJavaCamelroute-WhycanInotusewhenotherwiseinaJavaCamelroute]]
= Why can I not use when/otherwise in a Java Camel route?

When using the xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based Router] in
the Java DSL you may have a situation where the compiler will not accept
the following `when()` or `otherwise()` statement.

[TIP]
====
**Quick tip**

Use `.endChoice()` to return "back" to the
xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based Router].
====

For example as shown in the route below where we use the
xref:{eip-vc}:eips:loadBalance-eip.adoc[Load Balancer] inside the
xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based Router] in the first when:

*Code will not compile*

[source,java]
----
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 xref:{eip-vc}:eips:loadBalance-eip.adoc[Load Balancer]
uses the additional routing to know what to use in the load balancing.
In this example that would be the:

[source,java]
----
.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*

[source,java]
----
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
xref:ROOT:dsl.adoc[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
xref:{eip-vc}:eips:content-based-router-eip.adoc[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 xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based
Router].

*Code compiles*

[source,java]
----
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
xref:{eip-vc}:eips:enterprise-integration-patterns.adoc[EIP]s which often have additional
methods to configure or as part of the
xref:{eip-vc}:eips:enterprise-integration-patterns.adoc[EIP] itself. For example the
xref:{eip-vc}:eips:split-eip.adoc[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 xref:{eip-vc}:eips:content-based-router-eip.adoc[Content Based Router]. Note
`.endChoice()` is *Since Camel 2.7*.

[[WhycanInotusewhenorotherwiseinaJavaCamelroute-Stillproblems]]
== Still problems

If there are still problems, then you can split your route into multiple
routes, and link them together using the xref:components::direct-component.adoc[Direct]
component.
There can be some combinations of xref:{eip-vc}:eips:enterprise-integration-patterns.adoc[EIP]s
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).
