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 2020/10/02 08:50:41 UTC

[camel] 01/14: CAMEL-15605: Languages should be singleton for better performance.

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 eb06b1f4ba8e65356fb0162cdeb514f0f3f53868
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 1 13:10:52 2020 +0200

    CAMEL-15605: Languages should be singleton for better performance.
---
 .../apache/camel/language/bean/BeanLanguage.java   | 89 +++++-----------------
 .../main/java/org/apache/camel/spi/Language.java   | 28 +++++++
 .../camel/impl/engine/AbstractCamelContext.java    |  2 +
 .../camel/model/language/MethodCallExpression.java |  6 +-
 .../camel/reifier/language/ExpressionReifier.java  | 13 +++-
 .../language/JsonPathExpressionReifier.java        |  2 +
 .../language/MethodCallExpressionReifier.java      | 30 ++++++--
 .../reifier/language/SimpleExpressionReifier.java  | 27 +++++--
 .../language/TokenizerExpressionReifier.java       |  2 +
 .../language/XMLTokenizerExpressionReifier.java    |  2 +
 .../reifier/language/XPathExpressionReifier.java   |  2 +
 .../reifier/language/XQueryExpressionReifier.java  |  2 +
 .../camel/language/tokenizer/TokenizeLanguage.java |  8 +-
 .../support/ExpressionToPredicateAdapter.java      |  3 +
 .../camel/support/builder/ExpressionBuilder.java   | 14 ++--
 15 files changed, 133 insertions(+), 97 deletions(-)

diff --git a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
index c85395d..70d6692 100644
--- a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
+++ b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
@@ -16,13 +16,12 @@
  */
 package org.apache.camel.language.bean;
 
-import org.apache.camel.CamelContext;
+import java.util.Map;
+
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
 import org.apache.camel.support.ExpressionToPredicateAdapter;
 import org.apache.camel.support.LanguageSupport;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -37,88 +36,42 @@ import org.apache.camel.util.StringHelper;
  * As of Camel 1.5 the bean language also supports invoking a provided bean by its classname or the bean itself.
  */
 @org.apache.camel.spi.annotations.Language("bean")
-public class BeanLanguage extends LanguageSupport implements GeneratedPropertyConfigurer {
-
-    private Object bean;
-    private Class<?> beanType;
-    private String ref;
-    private String method;
+public class BeanLanguage extends LanguageSupport {
 
     public BeanLanguage() {
     }
 
     @Override
-    public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) {
-        if (target != this) {
-            throw new IllegalStateException("Can only configure our own instance !");
-        }
-        switch (ignoreCase ? name.toLowerCase() : name) {
-            case "bean":
-                setBean(PropertyConfigurerSupport.property(camelContext, Object.class, value));
-                return true;
-            case "beantype":
-            case "beanType":
-                setBeanType(PropertyConfigurerSupport.property(camelContext, Class.class, value));
-                return true;
-            case "ref":
-                setRef(PropertyConfigurerSupport.property(camelContext, String.class, value));
-                return true;
-            case "method":
-                setMethod(PropertyConfigurerSupport.property(camelContext, String.class, value));
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    public Object getBean() {
-        return bean;
-    }
-
-    public void setBean(Object bean) {
-        this.bean = bean;
-    }
-
-    public Class<?> getBeanType() {
-        return beanType;
-    }
-
-    public void setBeanType(Class<?> beanType) {
-        this.beanType = beanType;
-    }
-
-    public String getRef() {
-        return ref;
-    }
-
-    public void setRef(String ref) {
-        this.ref = ref;
-    }
-
-    public String getMethod() {
-        return method;
-    }
-
-    public void setMethod(String method) {
-        this.method = method;
+    public Predicate createPredicate(String expression) {
+        return ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
     }
 
     @Override
-    public Predicate createPredicate(String expression) {
-        return ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
+    public Predicate createPredicate(Map<String, Object> properties) {
+        return ExpressionToPredicateAdapter.toPredicate(createExpression(properties));
     }
 
     @Override
-    public Expression createExpression(String expression) {
-        // favour using the configured options
+    public Expression createExpression(Map<String, Object> properties) {
+        Object bean = properties.get("bean");
+        Class<?> beanType = (Class<?>) properties.get("beanType");
+        String ref = (String) properties.get("ref");
+        String method = (String) properties.get("method");
+
         if (bean != null) {
             return new BeanExpression(bean, method);
         } else if (beanType != null) {
             return new BeanExpression(beanType, method);
         } else if (ref != null) {
             return new BeanExpression(ref, method);
+        } else {
+            throw new IllegalArgumentException("Bean language requires bean, beanType, or ref argument");
         }
+    }
 
+    @Override
+    public Expression createExpression(String expression) {
+        // favour using the configured options
         String beanName = expression;
         String method = null;
 
@@ -147,8 +100,4 @@ public class BeanLanguage extends LanguageSupport implements GeneratedPropertyCo
         return new BeanExpression(beanName, method);
     }
 
-    @Override
-    public boolean isSingleton() {
-        return false;
-    }
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Language.java b/core/camel-api/src/main/java/org/apache/camel/spi/Language.java
index a666d4d5..1376c76 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Language.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Language.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.spi;
 
+import java.util.Map;
+
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
 
@@ -39,4 +41,30 @@ public interface Language {
      * @return            the created expression
      */
     Expression createExpression(String expression);
+
+    /**
+     * Creates an expression based on the given inputs properties
+     *
+     * This is used for languages that have been configured with custom properties
+     * most noticeable for xpath/xquery/tokenizer languages that have several options.
+     *
+     * @param  properties arguments
+     * @return            the created predicate
+     */
+    default Predicate createPredicate(Map<String, Object> properties) {
+        return null;
+    }
+
+    /**
+     * Creates an expression based on the given inputs properties
+     *
+     * This is used for languages that have been configured with custom properties
+     * most noticeable for xpath/xquery/tokenizer languages that have several options.
+     *
+     * @param  properties arguments
+     * @return            the created expression
+     */
+    default Expression createExpression(Map<String, Object> properties) {
+        return null;
+    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index e80f52f..93c92b5 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -1637,6 +1637,8 @@ public abstract class AbstractCamelContext extends BaseService
 
     @Override
     public Language resolveLanguage(String language) {
+        LOG.debug("Resolving language: {}", language);
+
         Language answer;
         synchronized (languages) {
             // as first iteration, check if there is a language instance for the given name
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
index 82870b0..4be866e 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
@@ -51,7 +51,7 @@ public class MethodCallExpression extends ExpressionDefinition {
     }
 
     public MethodCallExpression(String beanName, String method) {
-        super((String) null); // we dont use @XmlValue but the attributes instead
+        super(""); // we dont use @XmlValue but the attributes instead
         if (beanName != null && beanName.startsWith("ref:")) {
             beanName = beanName.substring(4);
         } else if (beanName != null && beanName.startsWith("bean:")) {
@@ -66,7 +66,7 @@ public class MethodCallExpression extends ExpressionDefinition {
     }
 
     public MethodCallExpression(Object instance, String method) {
-        super((String) null); // we dont use @XmlValue but the attributes instead
+        super(""); // we dont use @XmlValue but the attributes instead
         // must use setter as they have special logic
         setInstance(instance);
         setMethod(method);
@@ -77,7 +77,7 @@ public class MethodCallExpression extends ExpressionDefinition {
     }
 
     public MethodCallExpression(Class<?> type, String method) {
-        super((String) null); // we dont use @XmlValue but the attributes instead
+        super(""); // we dont use @XmlValue but the attributes instead
         setBeanType(type);
         setBeanTypeName(type.getName());
         setMethod(method);
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
index 01e7714..526615d 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
@@ -132,7 +132,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
                 // the classpath/file etc
                 exp = ScriptHelper.resolveOptionalExternalScript(camelContext, exp);
                 configureLanguage(language);
-                expression = language.createExpression(exp);
+                expression = createExpression(language, exp);
                 configureExpression(expression);
             }
         }
@@ -168,7 +168,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
                 // the classpath/file etc
                 exp = ScriptHelper.resolveOptionalExternalScript(camelContext, exp);
                 configureLanguage(language);
-                predicate = language.createPredicate(exp);
+                predicate = createPredicate(language, exp);
                 configurePredicate(predicate);
             }
         }
@@ -180,6 +180,14 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
         return predicate;
     }
 
+    protected Expression createExpression(Language language, String exp) {
+        return language.createExpression(exp);
+    }
+
+    protected Predicate createPredicate(Language language, String exp) {
+        return language.createPredicate(exp);
+    }
+
     protected void configureLanguage(Language language) {
     }
 
@@ -201,6 +209,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
         }
     }
 
+    @Deprecated
     protected void setProperties(Object target, Map<String, Object> properties) {
         properties.entrySet().removeIf(e -> e.getValue() == null);
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
index 471c0c3..669386d 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
@@ -27,6 +27,8 @@ import org.apache.camel.model.language.JsonPathExpression;
 
 public class JsonPathExpressionReifier extends ExpressionReifier<JsonPathExpression> {
 
+    // TODO: Update me
+
     public JsonPathExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) {
         super(camelContext, (JsonPathExpression) definition);
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java
index b736416..e6c3b52 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java
@@ -20,7 +20,9 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.MethodCallExpression;
 import org.apache.camel.spi.Language;
@@ -31,18 +33,36 @@ public class MethodCallExpressionReifier extends ExpressionReifier<MethodCallExp
         super(camelContext, (MethodCallExpression) definition);
     }
 
-    protected void configureLanguage(Language language) {
-        Map<String, Object> properties = new HashMap<>();
+    protected Map<String, Object> createProperties() {
+        Map<String, Object> properties = new HashMap<>(4);
         properties.put("bean", definition.getInstance());
         properties.put("beanType", or(definition.getBeanType(), definition.getBeanTypeName()));
         properties.put("ref", definition.getRef());
         properties.put("method", definition.getMethod());
-        setProperties(language, properties);
+        return properties;
     }
 
     @Override
-    public Predicate createPredicate() {
-        return (Predicate) createExpression();
+    protected void configureLanguage(Language language) {
+        if (definition.getBeanType() == null && definition.getBeanTypeName() != null) {
+            try {
+                Class<?> clazz = camelContext.getClassResolver().resolveMandatoryClass(definition.getBeanTypeName());
+                definition.setBeanType(clazz);
+            } catch (ClassNotFoundException e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+        }
     }
 
+    @Override
+    protected Expression createExpression(Language language, String exp) {
+        // method call does not use the string exp so its not in use
+        return language.createExpression(createProperties());
+    }
+
+    @Override
+    protected Predicate createPredicate(Language language, String exp) {
+        // method call does not use the string exp so its not in use
+        return language.createPredicate(createProperties());
+    }
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
index f740b3b..2bc0a3b 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
@@ -16,16 +16,15 @@
  */
 package org.apache.camel.reifier.language;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.SimpleBuilder;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.SimpleExpression;
+import org.apache.camel.spi.Language;
 
 public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression> {
 
@@ -68,15 +67,29 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression>
     protected SimpleBuilder createBuilder() {
         String exp = parseString(definition.getExpression());
         // should be true by default
-        boolean isTrim = parseBoolean(definition.getTrim(), true);
+        boolean isTrim = true;
+        if (definition.getTrim() != null) {
+            isTrim = parseBoolean(definition.getTrim());
+        }
         if (exp != null && isTrim) {
             exp = exp.trim();
         }
         SimpleBuilder answer = new SimpleBuilder(exp);
-        Map<String, Object> props = new HashMap<>();
-        props.put("resultType", or(definition.getResultType(), definition.getResultTypeName()));
-        setProperties(answer, props);
+        answer.setResultType(definition.getResultType());
         return answer;
     }
 
+    @Override
+    protected void configureLanguage(Language language) {
+        if (definition.getResultType() == null && definition.getResultTypeName() != null) {
+            Class<?> clazz;
+            try {
+                clazz = camelContext.getClassResolver().resolveMandatoryClass(definition.getResultTypeName());
+            } catch (ClassNotFoundException e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+            definition.setResultType(clazz);
+        }
+    }
+
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java
index ef08490..0f12413 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java
@@ -29,6 +29,8 @@ import org.apache.camel.support.ExpressionToPredicateAdapter;
 
 public class TokenizerExpressionReifier extends ExpressionReifier<TokenizerExpression> {
 
+    // TODO: Update me
+
     public TokenizerExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) {
         super(camelContext, (TokenizerExpression) definition);
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
index 2676560..aac9085 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java
@@ -28,6 +28,8 @@ import org.apache.camel.spi.NamespaceAware;
 
 public class XMLTokenizerExpressionReifier extends ExpressionReifier<XMLTokenizerExpression> {
 
+    // TODO: Update me
+
     public XMLTokenizerExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) {
         super(camelContext, (XMLTokenizerExpression) definition);
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
index 6cae1e0..a34af0f 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java
@@ -28,6 +28,8 @@ import org.apache.camel.spi.NamespaceAware;
 
 public class XPathExpressionReifier extends ExpressionReifier<XPathExpression> {
 
+    // TODO: Update me
+
     public XPathExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) {
         super(camelContext, (XPathExpression) definition);
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
index 2e0985a..4fb2ee2 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
@@ -28,6 +28,8 @@ import org.apache.camel.spi.NamespaceAware;
 
 public class XQueryExpressionReifier extends ExpressionReifier<XQueryExpression> {
 
+    // TODO: Update me
+
     public XQueryExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) {
         super(camelContext, (XQueryExpression) definition);
     }
diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
index 3007be6..20df970 100644
--- a/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
+++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java
@@ -61,7 +61,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur
         TokenizeLanguage language = new TokenizeLanguage();
         language.setToken(token);
         language.setRegex(regex);
-        return language.createExpression(null);
+        return language.createExpression((String) null);
     }
 
     public static Expression tokenize(String headerName, String token) {
@@ -73,7 +73,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur
         language.setHeaderName(headerName);
         language.setToken(token);
         language.setRegex(regex);
-        return language.createExpression(null);
+        return language.createExpression((String) null);
     }
 
     public static Expression tokenizePair(String startToken, String endToken, boolean includeTokens) {
@@ -81,7 +81,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur
         language.setToken(startToken);
         language.setEndToken(endToken);
         language.setIncludeTokens(includeTokens);
-        return language.createExpression(null);
+        return language.createExpression((String) null);
     }
 
     public static Expression tokenizeXML(String tagName, String inheritNamespaceTagName) {
@@ -89,7 +89,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur
         language.setToken(tagName);
         language.setInheritNamespaceTagName(inheritNamespaceTagName);
         language.setXml(true);
-        return language.createExpression(null);
+        return language.createExpression((String) null);
     }
 
     @Override
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
index f8e3808..e2ecf1f 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
@@ -54,6 +54,9 @@ public final class ExpressionToPredicateAdapter implements Predicate, CamelConte
      * Converts the given expression into an {@link Predicate}
      */
     public static Predicate toPredicate(final Expression expression) {
+        if (expression instanceof Predicate) {
+            return (Predicate) expression;
+        }
         return new ExpressionToPredicateAdapter(expression);
     }
 
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
index 19b8fa4..c180124 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
@@ -20,6 +20,7 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -1529,17 +1530,18 @@ public class ExpressionBuilder {
         };
     }
 
-    public static Expression beanExpression(final Object bean, final String expression) {
+    public static Expression beanExpression(final Object bean, final String method) {
         return new ExpressionAdapter() {
             public Object evaluate(Exchange exchange) {
                 Language language = exchange.getContext().resolveLanguage("bean");
-                setProperty(exchange.getContext(), language, "bean", bean);
-                setProperty(exchange.getContext(), language, "method", expression);
-                return language.createExpression(null).evaluate(exchange, Object.class);
+                Map<String, Object> properties = new HashMap<>(2);
+                properties.put("bean", bean);
+                properties.put("method", method);
+                return language.createExpression(properties).evaluate(exchange, Object.class);
             }
 
             public String toString() {
-                return "bean(" + bean + ", " + expression + ")";
+                return "bean(" + bean + ", " + method + ")";
             }
         };
     }
@@ -1623,7 +1625,7 @@ public class ExpressionBuilder {
                     setProperty(exchange.getContext(), language, "namespaces", namespaces);
                 }
                 setProperty(exchange.getContext(), language, "path", path);
-                return language.createExpression(null).evaluate(exchange, Object.class);
+                return language.createExpression((String)null).evaluate(exchange, Object.class);
             }
 
             @Override