You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/01/27 10:24:21 UTC

[camel] branch master updated (65632ea -> b1bc768)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 65632ea  Add Azure group to datalake docs
     new 822ba07  CAMEL-16082: Fix Java DSL expression vs predicate when using predicates via ExpressionClause (delegate) making it harder to know if it was a expression or predicate. So introducing PredicateFactory/Aware and initPredicate to handle predicates differently than expressions.
     new b1bc768  Fixed duplicate artifact in parent/pom.xml

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/java/org/apache/camel/Predicate.java  |  9 +++
 ...xpressionFactory.java => PredicateFactory.java} | 10 +--
 ...reProcessor.java => PredicateFactoryAware.java} | 10 +--
 .../org/apache/camel/builder/ExpressionClause.java | 22 +++++-
 .../camel/builder/ExpressionClauseSupport.java     | 72 ++++++++++++-------
 .../camel/model/language/ExpressionDefinition.java | 16 ++++-
 .../apache/camel/processor/ChoiceProcessor.java    |  2 +-
 .../camel/reifier/language/ExpressionReifier.java  |  4 +-
 .../ChoiceNoOtherwiseTest.java}                    | 80 ++++++++++++----------
 parent/pom.xml                                     |  5 --
 10 files changed, 147 insertions(+), 83 deletions(-)
 copy core/camel-api/src/main/java/org/apache/camel/{ExpressionFactory.java => PredicateFactory.java} (80%)
 copy core/camel-api/src/main/java/org/apache/camel/spi/{WrapAwareProcessor.java => PredicateFactoryAware.java} (77%)
 copy core/camel-core/src/test/java/org/apache/camel/{component/bean/BeanOverloadedCovariantMethodTest.java => processor/ChoiceNoOtherwiseTest.java} (50%)


[camel] 02/02: Fixed duplicate artifact in parent/pom.xml

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit b1bc76867e3d821d0ad2141db3f2281e4609bb4b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Jan 27 11:10:35 2021 +0100

    Fixed duplicate artifact in parent/pom.xml
---
 parent/pom.xml | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/parent/pom.xml b/parent/pom.xml
index 1494859..0c5c9b3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -2701,11 +2701,6 @@
 				<artifactId>camel-zookeeper</artifactId>
 				<version>${project.version}</version>
 			</dependency>
-			<dependency>
-                <groupId>org.apache.camel</groupId>
-                <artifactId>camel-csimple-joor</artifactId>
-                <version>${project.version}</version>
-            </dependency>
 			<!-- camel components: END -->
 
             <!-- camel catalog -->


[camel] 01/02: CAMEL-16082: Fix Java DSL expression vs predicate when using predicates via ExpressionClause (delegate) making it harder to know if it was a expression or predicate. So introducing PredicateFactory/Aware and initPredicate to handle predicates differently than expressions.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 822ba0794181da3d440e141eba9b5317e0795e01
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Jan 27 10:58:19 2021 +0100

    CAMEL-16082: Fix Java DSL expression vs predicate when using predicates via ExpressionClause (delegate) making it harder to know if it was a expression or predicate. So introducing PredicateFactory/Aware and initPredicate to handle predicates differently than expressions.
---
 .../src/main/java/org/apache/camel/Predicate.java  |   9 ++
 .../java/org/apache/camel/PredicateFactory.java    |  33 ++++++
 .../apache/camel/spi/PredicateFactoryAware.java    |  31 ++++++
 .../org/apache/camel/builder/ExpressionClause.java |  22 +++-
 .../camel/builder/ExpressionClauseSupport.java     |  72 +++++++-----
 .../camel/model/language/ExpressionDefinition.java |  16 ++-
 .../apache/camel/processor/ChoiceProcessor.java    |   2 +-
 .../camel/reifier/language/ExpressionReifier.java  |   4 +-
 .../camel/processor/ChoiceNoOtherwiseTest.java     | 122 +++++++++++++++++++++
 9 files changed, 281 insertions(+), 30 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/Predicate.java b/core/camel-api/src/main/java/org/apache/camel/Predicate.java
index b8bc9ed..851ffc5 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Predicate.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Predicate.java
@@ -42,4 +42,13 @@ public interface Predicate {
     default void init(CamelContext context) {
     }
 
+    /**
+     * Initialize as a predicate with the given camel context
+     *
+     * @param context the camel context
+     */
+    default void initPredicate(CamelContext context) {
+        init(context);
+    }
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/PredicateFactory.java b/core/camel-api/src/main/java/org/apache/camel/PredicateFactory.java
new file mode 100644
index 0000000..d8c4fd7
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/PredicateFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel;
+
+/**
+ * A factory for creating {@link Predicate}
+ */
+@FunctionalInterface
+public interface PredicateFactory {
+
+    /**
+     * Creates a predicate
+     *
+     * @param  camelContext the camel context
+     * @return              the created predicate.
+     */
+    Predicate createPredicate(CamelContext camelContext);
+
+}
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/PredicateFactoryAware.java b/core/camel-api/src/main/java/org/apache/camel/spi/PredicateFactoryAware.java
new file mode 100644
index 0000000..5a6e5d0
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/PredicateFactoryAware.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spi;
+
+import org.apache.camel.PredicateFactory;
+
+/**
+ * When an instance is aware of {@link org.apache.camel.PredicateFactory}.
+ */
+public interface PredicateFactoryAware {
+
+    /**
+     * Gets the {@link PredicateFactory}.
+     */
+    PredicateFactory getPredicateFactory();
+
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClause.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClause.java
index b8bdbc5..1e002ef 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClause.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClause.java
@@ -38,6 +38,7 @@ import org.apache.camel.support.builder.Namespaces;
 public class ExpressionClause<T> implements Expression, Predicate {
     private ExpressionClauseSupport<T> delegate;
     private volatile Expression expr;
+    private volatile Predicate pred;
 
     public ExpressionClause(T result) {
         this.delegate = new ExpressionClauseSupport<>(result);
@@ -998,6 +999,23 @@ public class ExpressionClause<T> implements Expression, Predicate {
     }
 
     @Override
+    public void initPredicate(CamelContext context) {
+        if (pred == null) {
+            synchronized (this) {
+                if (pred == null) {
+                    Expression newExpression = getExpressionValue();
+                    if (newExpression == null) {
+                        pred = delegate.getPredicateType().createPredicate(context);
+                    } else {
+                        pred = ExpressionToPredicateAdapter.toPredicate(newExpression);
+                    }
+                    pred.initPredicate(context);
+                }
+            }
+        }
+    }
+
+    @Override
     public <T> T evaluate(Exchange exchange, Class<T> type) {
         init(exchange.getContext());
         return expr.evaluate(exchange, type);
@@ -1005,7 +1023,7 @@ public class ExpressionClause<T> implements Expression, Predicate {
 
     @Override
     public boolean matches(Exchange exchange) {
-        init(exchange.getContext());
-        return new ExpressionToPredicateAdapter(expr).matches(exchange);
+        initPredicate(exchange.getContext());
+        return pred.matches(exchange);
     }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
index 2c84ab2..382b460 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
@@ -22,6 +22,7 @@ import org.apache.camel.BeanScope;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionFactory;
+import org.apache.camel.PredicateFactory;
 import org.apache.camel.model.language.CSimpleExpression;
 import org.apache.camel.model.language.ConstantExpression;
 import org.apache.camel.model.language.DatasonnetExpression;
@@ -43,12 +44,13 @@ import org.apache.camel.model.language.XMLTokenizerExpression;
 import org.apache.camel.model.language.XPathExpression;
 import org.apache.camel.model.language.XQueryExpression;
 import org.apache.camel.spi.ExpressionFactoryAware;
+import org.apache.camel.spi.PredicateFactoryAware;
 import org.apache.camel.support.builder.Namespaces;
 
 /**
  * A support class for building expression clauses.
  */
-public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
+public class ExpressionClauseSupport<T> implements ExpressionFactoryAware, PredicateFactoryAware {
 
     // Implementation detail: We must use the specific model.language.xxx
     // classes to make the DSL use these specific types
@@ -58,6 +60,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     private T result;
     private Expression expressionValue;
     private ExpressionFactory expressionType;
+    private PredicateFactory predicateType;
 
     public ExpressionClauseSupport(T result) {
         this.result = result;
@@ -70,8 +73,14 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
      * Specify an {@link org.apache.camel.Expression} instance
      */
     public T expression(Expression expression) {
-        if (expression instanceof ExpressionFactory) {
-            setExpressionType((ExpressionFactory) expression);
+        if (expression instanceof ExpressionFactory || expression instanceof PredicateFactory) {
+            // it can be both an expression and predicate
+            if (expression instanceof ExpressionFactory) {
+                setExpressionType((ExpressionFactory) expression);
+            }
+            if (expression instanceof PredicateFactory) {
+                setPredicateType((PredicateFactory) expression);
+            }
         } else {
             setExpressionValue(expression);
         }
@@ -384,7 +393,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T jsonpath(String text, Class<?> resultType) {
         JsonPathExpression expression = new JsonPathExpression(text);
         expression.setResultType(resultType);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -400,7 +409,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         JsonPathExpression expression = new JsonPathExpression(text);
         expression.setSuppressExceptions(Boolean.toString(suppressExceptions));
         expression.setResultType(resultType);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -418,7 +427,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setSuppressExceptions(Boolean.toString(suppressExceptions));
         expression.setAllowSimple(Boolean.toString(allowSimple));
         expression.setResultType(resultType);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -438,7 +447,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setAllowSimple(Boolean.toString(allowSimple));
         expression.setResultType(resultType);
         expression.setHeaderName(headerName);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -584,7 +593,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T simple(String text, Class<?> resultType) {
         SimpleExpression expression = new SimpleExpression(text);
         expression.setResultType(resultType);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -678,7 +687,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setToken(token);
         expression.setHeaderName(headerName);
         expression.setRegex(Boolean.toString(regex));
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -710,7 +719,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setHeaderName(headerName);
         expression.setRegex(Boolean.toString(regex));
         expression.setSkipFirst(Boolean.toString(skipFirst));
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -761,7 +770,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setGroup(group);
         expression.setGroupDelimiter(groupDelimiter);
         expression.setSkipFirst(Boolean.toString(skipFirst));
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -778,7 +787,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setToken(startToken);
         expression.setEndToken(endToken);
         expression.setIncludeTokens(Boolean.toString(includeTokens));
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -808,7 +817,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setInheritNamespaceTagName(inheritNamespaceTagName);
         expression.setXml(Boolean.toString(true));
         expression.setGroup(group);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -830,7 +839,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         if (group > 0) {
             expression.setGroup(Integer.toString(group));
         }
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -868,7 +877,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T xpath(String text, Class<?> resultType) {
         XPathExpression expression = new XPathExpression(text);
         expression.setResultType(resultType);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -884,7 +893,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T xpath(String text, Class<?> resultType, String headerName) {
         XPathExpression expression = new XPathExpression(text);
         expression.setHeaderName(headerName);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -916,7 +925,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setResultType(resultType);
         expression.setNamespaces(namespaces.getNamespaces());
         expression.setHeaderName(headerName);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -933,7 +942,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         XPathExpression expression = new XPathExpression(text);
         expression.setResultType(resultType);
         expression.setNamespaces(namespaces);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -960,7 +969,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T xpath(String text, Map<String, String> namespaces) {
         XPathExpression expression = new XPathExpression(text);
         expression.setNamespaces(namespaces);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -997,7 +1006,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T xquery(String text, Class<?> resultType) {
         XQueryExpression expression = new XQueryExpression(text);
         expression.setResultType(resultType);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -1012,7 +1021,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T xquery(String text, Class<?> resultType, String headerName) {
         XQueryExpression expression = new XQueryExpression(text);
         expression.setHeaderName(headerName);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -1044,7 +1053,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         expression.setResultType(resultType);
         expression.setNamespaces(namespaces.getNamespaces());
         expression.setHeaderName(headerName);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -1061,7 +1070,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         XQueryExpression expression = new XQueryExpression(text);
         expression.setResultType(resultType);
         expression.setNamespaces(namespaces);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -1088,7 +1097,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
     public T xquery(String text, Map<String, String> namespaces) {
         XQueryExpression expression = new XQueryExpression(text);
         expression.setNamespaces(namespaces);
-        setExpressionType(expression);
+        expression(expression);
         return result;
     }
 
@@ -1101,7 +1110,7 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
      */
     public T language(String language, String expression) {
         LanguageExpression exp = new LanguageExpression(language, expression);
-        setExpressionType(exp);
+        expression(exp);
         return result;
     }
 
@@ -1129,6 +1138,19 @@ public class ExpressionClauseSupport<T> implements ExpressionFactoryAware {
         return expressionType;
     }
 
+    public PredicateFactory getPredicateType() {
+        return predicateType;
+    }
+
+    public void setPredicateType(PredicateFactory predicateType) {
+        this.predicateType = predicateType;
+    }
+
+    @Override
+    public PredicateFactory getPredicateFactory() {
+        return predicateType;
+    }
+
     protected Expression createExpression(CamelContext camelContext) {
         if (getExpressionValue() == null) {
             if (getExpressionType() != null) {
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
index a675d2a..cc84a74 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
@@ -33,9 +33,11 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionFactory;
 import org.apache.camel.Predicate;
+import org.apache.camel.PredicateFactory;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.spi.ExpressionFactoryAware;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.PredicateFactoryAware;
 import org.apache.camel.util.ObjectHelper;
 
 /**
@@ -46,7 +48,8 @@ import org.apache.camel.util.ObjectHelper;
 @XmlType(name = "expression") // must be named expression
 @XmlAccessorType(XmlAccessType.FIELD)
 @SuppressWarnings("rawtypes")
-public class ExpressionDefinition implements Expression, Predicate, ExpressionFactory, ExpressionFactoryAware {
+public class ExpressionDefinition
+        implements Expression, Predicate, ExpressionFactory, ExpressionFactoryAware, PredicateFactory, PredicateFactoryAware {
     @XmlAttribute
     @XmlID
     private String id;
@@ -196,6 +199,11 @@ public class ExpressionDefinition implements Expression, Predicate, ExpressionFa
     }
 
     @Override
+    public PredicateFactory getPredicateFactory() {
+        return this;
+    }
+
+    @Override
     public Expression createExpression(CamelContext camelContext) {
         return camelContext.adapt(ModelCamelContext.class).createExpression(this);
     }
@@ -240,4 +248,10 @@ public class ExpressionDefinition implements Expression, Predicate, ExpressionFa
         }
     }
 
+    @Override
+    public void initPredicate(CamelContext context) {
+        if (predicate == null) {
+            predicate = createPredicate(context);
+        }
+    }
 }
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/ChoiceProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/ChoiceProcessor.java
index f57e3b1..cf80e7e 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/ChoiceProcessor.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/ChoiceProcessor.java
@@ -51,7 +51,7 @@ public class ChoiceProcessor extends AsyncProcessorSupport implements Navigate<P
 
     public ChoiceProcessor(List<FilterProcessor> filters, Processor otherwise) {
         this.filters = filters;
-        this.otherwise = AsyncProcessorConverterHelper.convert(otherwise);
+        this.otherwise = otherwise != null ? AsyncProcessorConverterHelper.convert(otherwise) : null;
     }
 
     @Override
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
index 4e50324..0fb98a5 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
@@ -230,7 +230,9 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
         if (predicate instanceof CamelContextAware) {
             ((CamelContextAware) predicate).setCamelContext(camelContext);
         }
-        predicate.init(camelContext);
+        // if the predicate is created via a delegate then it would need to know if its a predicate or expression
+        // when being initialized
+        predicate.initPredicate(camelContext);
         return predicate;
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/ChoiceNoOtherwiseTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/ChoiceNoOtherwiseTest.java
new file mode 100644
index 0000000..18e5b01
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/ChoiceNoOtherwiseTest.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class ChoiceNoOtherwiseTest extends ContextTestSupport {
+    protected MockEndpoint x;
+    protected MockEndpoint end;
+
+    @Test
+    public void testNoOtherwise() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").choice().when().simple("${header.foo} == 'bar'").to("mock:x").end().to("mock:end");
+            }
+        });
+        context.start();
+
+        x.expectedBodiesReceived("a");
+        end.expectedBodiesReceived("a", "b");
+
+        sendMessage("bar", "a");
+        sendMessage("cheese", "b");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testNoOtherwiseTwo() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").choice().when(simple("${header.foo} == 'bar'")).to("mock:x").end().to("mock:end");
+            }
+        });
+        context.start();
+
+        x.expectedBodiesReceived("a");
+        end.expectedBodiesReceived("a", "b");
+
+        sendMessage("bar", "a");
+        sendMessage("cheese", "b");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testEmptyOtherwise() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").choice().when().simple("${header.foo} == 'bar'").to("mock:x").otherwise().end().to("mock:end");
+            }
+        });
+        context.start();
+
+        x.expectedBodiesReceived("a");
+        end.expectedBodiesReceived("a", "b");
+
+        sendMessage("bar", "a");
+        sendMessage("cheese", "b");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testEmptyOtherwiseTwo() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").choice().when(simple("${header.foo} == 'bar'")).to("mock:x").otherwise().end().to("mock:end");
+            }
+        });
+        context.start();
+
+        x.expectedBodiesReceived("a");
+        end.expectedBodiesReceived("a", "b");
+
+        sendMessage("bar", "a");
+        sendMessage("cheese", "b");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    protected void sendMessage(final Object headerValue, final Object body) throws Exception {
+        template.sendBodyAndHeader("direct:start", body, "foo", headerValue);
+    }
+
+    @Override
+    @BeforeEach
+    public void setUp() throws Exception {
+        super.setUp();
+
+        x = getMockEndpoint("mock:x");
+        end = getMockEndpoint("mock:end");
+    }
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+}