blob: 7c2220258aac366457d961a73bd928e90d8ca6ec [file] [log] [blame]
[[WhycanInotusewhenorotherwiseinaJavaCamelroute-WhycanInotusewhenotherwiseinaJavaCamelroute]]
= Why can I not use when/otherwise in a Java Camel route?
When using the xref: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:content-based-router-eip.adoc[Content Based Router].
====
For example as shown in the route below where we use the
xref:loadBalance-eip.adoc[Load Balancer] inside the
xref: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: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: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: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: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:enterprise-integration-patterns.adoc[EIP]s which often have additional
methods to configure or as part of the
xref:enterprise-integration-patterns.adoc[EIP] itself. For example the
xref: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: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: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).