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

davsclaus pushed a commit to branch backport/25729-to-camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 2e030bb270e26f3fe1e246dde8ef0f450f59b5df
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Aug 26 06:58:14 2026 +0200

    CAMEL-24486: camel-core - Simple language init block custom function lookup 
fails in dev profile
    
    DefaultSimpleFunctionRegistry.getFunction() always bypassed its own function
    cache when the CamelContext profile is dev, to support hot-reloading
    SimpleFunction beans from the registry. But custom functions defined via the
    Simple language init block ($foo ~:= <expr>;) are plain Expressions stored
    directly in that cache, not registry beans, so the dev-mode lookup always
    missed them and threw "No custom simple function with name: X". Since
    camel run (camel-jbang) defaults to --profile=dev, this broke the init-block
    custom-function feature for essentially every JBang user.
    
    Fall back to the already-registered function when no SimpleFunction bean is
    found in the registry.
    
    Co-authored-by: Claude Sonnet 5 <[email protected]>
    
    Closes #25729
---
 .../impl/engine/DefaultSimpleFunctionRegistry.java |  4 ++
 .../camel/dsl/yaml/SimpleInitBlockTest.groovy      | 65 ++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultSimpleFunctionRegistry.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultSimpleFunctionRegistry.java
index 706d14c14521..5f1927fd086d 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultSimpleFunctionRegistry.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultSimpleFunctionRegistry.java
@@ -110,6 +110,10 @@ public class DefaultSimpleFunctionRegistry extends 
ServiceSupport implements Sim
                 removeFunction(name);
                 addFunction(sf);
                 exp = functions.get(name);
+            } else if (dev) {
+                // fallback to an already registered function (eg from a 
simple language init block)
+                // that is not backed by a SimpleFunction bean in the registry
+                exp = functions.get(name);
             }
         }
         return exp;
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SimpleInitBlockTest.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SimpleInitBlockTest.groovy
index b24a58b38049..7f326742b653 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SimpleInitBlockTest.groovy
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SimpleInitBlockTest.groovy
@@ -57,4 +57,69 @@ class SimpleInitBlockTest extends YamlTestSupport {
         MockEndpoint.assertIsSatisfied(context)
     }
 
+    def "initBlockCompactCustomFunction"() {
+        setup:
+        loadRoutes '''
+                - route:
+                    from:
+                      uri: direct:map
+                      steps:
+                        - setBody:
+                            simple: |-
+                              $init{
+                                $foo ~:= ${uppercase()};
+                              }init$
+                              ${foo('hello')}
+                        - to:
+                            uri: mock:result
+                        '''
+        withMock('mock:result') {
+            expectedMessageCount(1)
+            message(0).body().isEqualTo("HELLO")
+        }
+
+        when:
+        context.start()
+
+        withTemplate {
+            to('direct:map').withBody('test').send()
+        }
+
+        then:
+        MockEndpoint.assertIsSatisfied(context)
+    }
+
+    def "initBlockCustomFunctionInDevProfile"() {
+        setup:
+        context.getCamelContextExtension().setProfile("dev")
+        loadRoutes '''
+                - route:
+                    from:
+                      uri: direct:map
+                      steps:
+                        - setBody:
+                            simple: |-
+                              $init{
+                                $foo ~:= ${uppercase()};
+                              }init$
+                              ${foo('hello')}
+                        - to:
+                            uri: mock:result
+                        '''
+        withMock('mock:result') {
+            expectedMessageCount(1)
+            message(0).body().isEqualTo("HELLO")
+        }
+
+        when:
+        context.start()
+
+        withTemplate {
+            to('direct:map').withBody('test').send()
+        }
+
+        then:
+        MockEndpoint.assertIsSatisfied(context)
+    }
+
 }

Reply via email to