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 2017/06/30 07:55:51 UTC

[1/2] camel git commit: CAMEL-11484: Optimise - Simple Language / ExpressionBuilder can use cache of frequent used expressions when having nested functions

Repository: camel
Updated Branches:
  refs/heads/master 99166b8e7 -> 52cede016


CAMEL-11484: Optimise - Simple Language / ExpressionBuilder can use cache of frequent used expressions when having nested functions


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b8f7e427
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b8f7e427
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b8f7e427

Branch: refs/heads/master
Commit: b8f7e4276754920bb60d118742fcfee7b12479b9
Parents: 99166b8
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Jun 30 08:59:01 2017 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Jun 30 08:59:09 2017 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/camel/Exchange.java    |   1 +
 .../camel/language/simple/SimpleLanguage.java   |  68 ++++++++---
 .../apache/camel/util/CamelContextHelper.java   |  31 +++++
 .../SimpleLanguageTransformRandomTest.java      |  44 ++++++++
 .../itest/jmh/SimpleCachedExpressionTest.java   | 112 -------------------
 .../camel/itest/jmh/SimpleExpressionTest.java   |   6 +-
 6 files changed, 133 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b8f7e427/camel-core/src/main/java/org/apache/camel/Exchange.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/Exchange.java b/camel-core/src/main/java/org/apache/camel/Exchange.java
index b4e1992..bfe9251 100644
--- a/camel-core/src/main/java/org/apache/camel/Exchange.java
+++ b/camel-core/src/main/java/org/apache/camel/Exchange.java
@@ -171,6 +171,7 @@ public interface Exchange {
 
     String MAXIMUM_CACHE_POOL_SIZE     = "CamelMaximumCachePoolSize";
     String MAXIMUM_ENDPOINT_CACHE_SIZE = "CamelMaximumEndpointCacheSize";
+    String MAXIMUM_SIMPLE_CACHE_SIZE = "CamelMaximumSimpleCacheSize";
     String MAXIMUM_TRANSFORMER_CACHE_SIZE = "CamelMaximumTransformerCacheSize";
     String MAXIMUM_VALIDATOR_CACHE_SIZE = "CamelMaximumValidatorCacheSize";
     String MESSAGE_HISTORY             = "CamelMessageHistory";

http://git-wip-us.apache.org/repos/asf/camel/blob/b8f7e427/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
index 20878c9..ab0aa36 100644
--- a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
@@ -16,10 +16,14 @@
  */
 package org.apache.camel.language.simple;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.support.LanguageSupport;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.LRUCache;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.PredicateToExpressionAdapter;
 
@@ -93,6 +97,10 @@ public class SimpleLanguage extends LanguageSupport {
     // singleton for expressions without a result type
     private static final SimpleLanguage SIMPLE = new SimpleLanguage();
 
+    // use caches to avoid re-parsing the same expressions over and over again
+    private LRUCache<String, Expression> cacheExpression;
+    private LRUCache<String, Predicate> cachePredicate;
+
     protected boolean allowEscape = true;
 
     /**
@@ -101,35 +109,63 @@ public class SimpleLanguage extends LanguageSupport {
     public SimpleLanguage() {
     }
 
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        super.setCamelContext(camelContext);
+
+        // setup cache which requires CamelContext to be set first
+        if (cacheExpression == null && cachePredicate == null && camelContext != null) {
+            int maxSize = CamelContextHelper.getMaximumSimpleCacheSize(camelContext);
+            cacheExpression = new LRUCache<>(16, maxSize, false);
+            cachePredicate = new LRUCache<>(16, maxSize, false);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
     public Predicate createPredicate(String expression) {
         ObjectHelper.notNull(expression, "expression");
 
-        expression = loadResource(expression);
-
-        // support old simple language syntax
-        @SuppressWarnings("deprecation")
-        Predicate answer = SimpleBackwardsCompatibleParser.parsePredicate(expression, allowEscape);
+        Predicate answer = cachePredicate != null ? cachePredicate.get(expression) : null;
         if (answer == null) {
-            // use the new parser
-            SimplePredicateParser parser = new SimplePredicateParser(expression, allowEscape);
-            answer = parser.parsePredicate();
+
+            expression = loadResource(expression);
+
+            // support old simple language syntax
+            answer = SimpleBackwardsCompatibleParser.parsePredicate(expression, allowEscape);
+            if (answer == null) {
+                // use the new parser
+                SimplePredicateParser parser = new SimplePredicateParser(expression, allowEscape);
+                answer = parser.parsePredicate();
+            }
+            if (cachePredicate != null) {
+                cachePredicate.put(expression, answer);
+            }
         }
+
         return answer;
     }
 
+    @SuppressWarnings("deprecation")
     public Expression createExpression(String expression) {
         ObjectHelper.notNull(expression, "expression");
 
-        expression = loadResource(expression);
-
-        // support old simple language syntax
-        @SuppressWarnings("deprecation")
-        Expression answer = SimpleBackwardsCompatibleParser.parseExpression(expression, allowEscape);
+        Expression answer = cacheExpression != null ? cacheExpression.get(expression) : null;
         if (answer == null) {
-            // use the new parser
-            SimpleExpressionParser parser = new SimpleExpressionParser(expression, allowEscape);
-            answer = parser.parseExpression();
+
+            expression = loadResource(expression);
+
+            // support old simple language syntax
+            answer = SimpleBackwardsCompatibleParser.parseExpression(expression, allowEscape);
+            if (answer == null) {
+                // use the new parser
+                SimpleExpressionParser parser = new SimpleExpressionParser(expression, allowEscape);
+                answer = parser.parseExpression();
+            }
+            if (cacheExpression != null) {
+                cacheExpression.put(expression, answer);
+            }
         }
+
         return answer;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/b8f7e427/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
index d126005..1ee219c 100644
--- a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
@@ -268,6 +268,37 @@ public final class CamelContextHelper {
     }
 
     /**
+     * Gets the maximum simple cache size.
+     * <p/>
+     * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_SIMPLE_CACHE_SIZE}.
+     * If no property has been set, then it will fallback to return a size of 1000.
+     *
+     * @param camelContext the camel context
+     * @return the maximum cache size
+     * @throws IllegalArgumentException is thrown if the property is illegal
+     */
+    public static int getMaximumSimpleCacheSize(CamelContext camelContext) throws IllegalArgumentException {
+        if (camelContext != null) {
+            String s = camelContext.getGlobalOption(Exchange.MAXIMUM_SIMPLE_CACHE_SIZE);
+            if (s != null) {
+                // we cannot use Camel type converters as they may not be ready this early
+                try {
+                    Integer size = Integer.valueOf(s);
+                    if (size == null || size <= 0) {
+                        throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_SIMPLE_CACHE_SIZE + " must be a positive number, was: " + s);
+                    }
+                    return size;
+                } catch (NumberFormatException e) {
+                    throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_SIMPLE_CACHE_SIZE + " must be a positive number, was: " + s, e);
+                }
+            }
+        }
+
+        // 1000 is the default fallback
+        return 1000;
+    }
+
+    /**
      * Gets the maximum transformer cache size.
      * <p/>
      * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_TRANSFORMER_CACHE_SIZE}.

http://git-wip-us.apache.org/repos/asf/camel/blob/b8f7e427/camel-core/src/test/java/org/apache/camel/language/SimpleLanguageTransformRandomTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/language/SimpleLanguageTransformRandomTest.java b/camel-core/src/test/java/org/apache/camel/language/SimpleLanguageTransformRandomTest.java
new file mode 100644
index 0000000..6280f4c
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/language/SimpleLanguageTransformRandomTest.java
@@ -0,0 +1,44 @@
+/**
+ * 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.language;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * Unit test routing with simple language using random function which will reuse cached expressions.
+ */
+public class SimpleLanguageTransformRandomTest extends ContextTestSupport {
+
+    public void testSimpleTransform() throws Exception {
+        int out = template.requestBodyAndHeader("direct:start", "Random number", "max", "5", int.class);
+        assertTrue(out <= 5);
+
+        out = template.requestBodyAndHeader("direct:start", "Random number", "max", "20", int.class);
+        assertTrue(out <= 20);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from("direct:start")
+                    .transform().simple("${random(1,${header.max})}");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b8f7e427/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleCachedExpressionTest.java
----------------------------------------------------------------------
diff --git a/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleCachedExpressionTest.java b/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleCachedExpressionTest.java
deleted file mode 100644
index 0532dde..0000000
--- a/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleCachedExpressionTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * 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.itest.jmh;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.Expression;
-import org.apache.camel.builder.ExpressionBuilder;
-import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.impl.DefaultExchange;
-import org.junit.Test;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.Level;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
-import org.openjdk.jmh.infra.Blackhole;
-import org.openjdk.jmh.runner.Runner;
-import org.openjdk.jmh.runner.options.Options;
-import org.openjdk.jmh.runner.options.OptionsBuilder;
-import org.openjdk.jmh.runner.options.TimeValue;
-
-/**
- * Tests a Simple expression
- */
-public class SimpleCachedExpressionTest {
-
-    @Test
-    public void launchBenchmark() throws Exception {
-        Options opt = new OptionsBuilder()
-            // Specify which benchmarks to run.
-            // You can be more specific if you'd like to run only one benchmark per test.
-            .include(this.getClass().getName() + ".*")
-            // Set the following options as needed
-            .mode(Mode.All)
-            .timeUnit(TimeUnit.MICROSECONDS)
-            .warmupTime(TimeValue.seconds(1))
-            .warmupIterations(2)
-            .measurementTime(TimeValue.seconds(1))
-            .measurementIterations(2)
-            .threads(2)
-            .forks(1)
-            .shouldFailOnError(true)
-            .shouldDoGC(true)
-            .build();
-
-        new Runner(opt).run();
-    }
-
-    // The JMH samples are the best documentation for how to use it
-    // http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
-    @State(Scope.Thread)
-    public static class BenchmarkState {
-        CamelContext camel;
-        String expression = "Hello ${body}";
-        Exchange exchange;
-        Expression cached;
-
-        @Setup(Level.Trial)
-        public void initialize() {
-            camel = new DefaultCamelContext();
-            try {
-                camel.start();
-                exchange = new DefaultExchange(camel);
-                exchange.getIn().setBody("World");
-                cached = ExpressionBuilder.simpleExpression(expression);
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-
-        @TearDown(Level.Trial)
-        public void close() {
-            try {
-                camel.stop();
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-
-    }
-
-    @Benchmark
-    @Measurement(batchSize = 1000)
-    public void simpleCachedExpression(BenchmarkState state, Blackhole bh) {
-        String out = state.cached.evaluate(state.exchange, String.class);
-        if (!out.equals("Hello World")) {
-            throw new IllegalArgumentException("Evaluation failed");
-        }
-        bh.consume(out);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/b8f7e427/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleExpressionTest.java
----------------------------------------------------------------------
diff --git a/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleExpressionTest.java b/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleExpressionTest.java
index 505504f..1c45768 100644
--- a/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleExpressionTest.java
+++ b/tests/camel-jmh/src/test/java/org/apache/camel/itest/jmh/SimpleExpressionTest.java
@@ -55,7 +55,7 @@ public class SimpleExpressionTest {
             .timeUnit(TimeUnit.MICROSECONDS)
             .warmupTime(TimeValue.seconds(1))
             .warmupIterations(2)
-            .measurementTime(TimeValue.seconds(1))
+            .measurementTime(TimeValue.seconds(10))
             .measurementIterations(2)
             .threads(2)
             .forks(1)
@@ -81,6 +81,10 @@ public class SimpleExpressionTest {
                 camel.start();
                 exchange = new DefaultExchange(camel);
                 exchange.getIn().setBody("World");
+
+                // warm up as we use cache on simple expression
+                ExpressionBuilder.simpleExpression(expression);
+
             } catch (Exception e) {
                 // ignore
             }


[2/2] camel git commit: CAMEL-11484: Optimise - Simple Language / ExpressionBuilder can use cache of frequent used expressions when having nested functions

Posted by da...@apache.org.
CAMEL-11484: Optimise - Simple Language / ExpressionBuilder can use cache of frequent used expressions when having nested functions


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/52cede01
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/52cede01
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/52cede01

Branch: refs/heads/master
Commit: 52cede0162ee1a2b81a70ed0ee220d1edf446bb8
Parents: b8f7e42
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Jun 30 09:41:01 2017 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Jun 30 09:45:25 2017 +0200

----------------------------------------------------------------------
 .../apache/camel/impl/DefaultCamelContext.java  |  3 ++
 .../camel/language/simple/SimpleLanguage.java   | 48 ++++++++++++++------
 .../camel/language/LanguageServiceTest.java     | 12 +++--
 3 files changed, 46 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/52cede01/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 4cb46f4..26a865d 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -3933,6 +3933,9 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
         if (isTypeConverterStatisticsEnabled() != null) {
             getTypeConverterRegistry().getStatistics().setStatisticsEnabled(isTypeConverterStatisticsEnabled());
         }
+
+        // resolve simple language to initialize it
+        resolveLanguage("simple");
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/camel/blob/52cede01/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
index ab0aa36..d62e909 100644
--- a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
+++ b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java
@@ -16,16 +16,17 @@
  */
 package org.apache.camel.language.simple;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
+import org.apache.camel.StaticService;
 import org.apache.camel.builder.ExpressionBuilder;
 import org.apache.camel.support.LanguageSupport;
 import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.LRUCache;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.PredicateToExpressionAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A <a href="http://camel.apache.org/simple.html">simple language</a>
@@ -90,19 +91,20 @@ import org.apache.camel.util.PredicateToExpressionAdapter;
  * return the full path including the starting directory.
  * <br/>
  * The <b>only</b> file is the filename only with all paths clipped.
- *
  */
-public class SimpleLanguage extends LanguageSupport {
+public class SimpleLanguage extends LanguageSupport implements StaticService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SimpleLanguage.class);
 
     // singleton for expressions without a result type
     private static final SimpleLanguage SIMPLE = new SimpleLanguage();
 
+    boolean allowEscape = true;
+
     // use caches to avoid re-parsing the same expressions over and over again
     private LRUCache<String, Expression> cacheExpression;
     private LRUCache<String, Predicate> cachePredicate;
 
-    protected boolean allowEscape = true;
-
     /**
      * Default constructor.
      */
@@ -110,14 +112,33 @@ public class SimpleLanguage extends LanguageSupport {
     }
 
     @Override
-    public void setCamelContext(CamelContext camelContext) {
-        super.setCamelContext(camelContext);
-
+    public void start() throws Exception {
         // setup cache which requires CamelContext to be set first
-        if (cacheExpression == null && cachePredicate == null && camelContext != null) {
-            int maxSize = CamelContextHelper.getMaximumSimpleCacheSize(camelContext);
-            cacheExpression = new LRUCache<>(16, maxSize, false);
-            cachePredicate = new LRUCache<>(16, maxSize, false);
+        if (cacheExpression == null && cachePredicate == null && getCamelContext() != null) {
+            int maxSize = CamelContextHelper.getMaximumSimpleCacheSize(getCamelContext());
+            if (maxSize > 0) {
+                cacheExpression = new LRUCache<>(16, maxSize, false);
+                cachePredicate = new LRUCache<>(16, maxSize, false);
+                LOG.debug("Simple language predicate/expression cache size: {}", maxSize);
+            } else {
+                LOG.debug("Simple language disabled predicate/expression cache");
+            }
+        }
+    }
+
+    @Override
+    public void stop() throws Exception {
+        if (cachePredicate != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Clearing simple language predicate cache[size={}, hits={}, misses={}, evicted={}]",
+                    cachePredicate.size(), cachePredicate.getHits(), cachePredicate.getMisses(), cachePredicate.getEvicted());
+            }
+        }
+        if (cacheExpression != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Clearing simple language expression cache[size={}, hits={}, misses={}, evicted={}]",
+                    cacheExpression.size(), cacheExpression.getHits(), cacheExpression.getMisses(), cacheExpression.getEvicted());
+            }
         }
     }
 
@@ -283,4 +304,5 @@ public class SimpleLanguage extends LanguageSupport {
     public void setFunctionEndToken(String endToken) {
         changeFunctionEndToken(endToken);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/52cede01/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java b/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java
index e87b775..6edfb9f 100644
--- a/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java
+++ b/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java
@@ -41,14 +41,16 @@ public class LanguageServiceTest extends ContextTestSupport {
         MyLanguage myl = (MyLanguage) context.resolveLanguage("my");
         assertNotNull(myl);
         assertEquals("Started", myl.getState());
-        assertEquals(1, context.getLanguageNames().size());
+        // simple language is resolved by default hence why there is 2
+        assertEquals(2, context.getLanguageNames().size());
 
         // resolve again, should find same instance
         MyLanguage myl2 = (MyLanguage) context.resolveLanguage("my");
         assertNotNull(myl2);
         assertSame(myl, myl2);
         assertEquals("Started", myl2.getState());
-        assertEquals(1, context.getLanguageNames().size());
+        // simple language is resolved by default hence why there is 2
+        assertEquals(2, context.getLanguageNames().size());
 
         context.stop();
         assertEquals("Stopped", myl.getState());
@@ -58,13 +60,15 @@ public class LanguageServiceTest extends ContextTestSupport {
     public void testNonSingletonLanguage() throws Exception {
         Language tol = context.resolveLanguage("tokenize");
         assertNotNull(tol);
-        assertEquals(1, context.getLanguageNames().size());
+        // simple language is resolved by default hence why there is 2
+        assertEquals(2, context.getLanguageNames().size());
 
         // resolve again, should find another instance
         Language tol2 = context.resolveLanguage("tokenize");
         assertNotNull(tol2);
         assertNotSame(tol, tol2);
-        assertEquals(1, context.getLanguageNames().size());
+        // simple language is resolved by default hence why there is 2
+        assertEquals(2, context.getLanguageNames().size());
 
         context.stop();
         assertTrue(context.getLanguageNames().isEmpty());