You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gg...@apache.org on 2020/05/14 12:56:52 UTC

[camel] branch CAMEL-15061-3.4.x created (now 790cba0)

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

ggrzybek pushed a change to branch CAMEL-15061-3.4.x
in repository https://gitbox.apache.org/repos/asf/camel.git.


      at 790cba0  [CAMEL-15061] Cache failed attempts to load classes to greatly improve performance

This branch includes the following new commits:

     new 790cba0  [CAMEL-15061] Cache failed attempts to load classes to greatly improve performance

The 1 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.



[camel] 01/01: [CAMEL-15061] Cache failed attempts to load classes to greatly improve performance

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

ggrzybek pushed a commit to branch CAMEL-15061-3.4.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 790cba05d465ea426a0488cc59149534c50fdb7c
Author: Grzegorz Grzybek <gr...@gmail.com>
AuthorDate: Thu May 14 14:50:03 2020 +0200

    [CAMEL-15061] Cache failed attempts to load classes to greatly improve performance
---
 .../camel/impl/engine/DefaultFactoryFinder.java     | 21 ++++++++++++++++++++-
 .../camel/impl/engine/DefaultFactoryFinderTest.java | 20 ++++++++++++++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java
index d1ecced..bd4f64e 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFactoryFinder.java
@@ -37,6 +37,8 @@ import org.apache.camel.util.IOHelper;
 public class DefaultFactoryFinder implements FactoryFinder {
 
     private final ConcurrentMap<String, Class<?>> classMap = new ConcurrentHashMap<>();
+    private final ConcurrentMap<String, Boolean> classesNotFound = new ConcurrentHashMap<>();
+    private final ConcurrentMap<String, Exception> classesNotFoundExceptions = new ConcurrentHashMap<>();
     private final ClassResolver classResolver;
     private final String path;
 
@@ -135,16 +137,33 @@ public class DefaultFactoryFinder implements FactoryFinder {
      * later on with the only purpose to re-throw the original exception.
      */
     protected Class<?> addToClassMap(String key, ClassSupplier mappingFunction) {
-        return classMap.computeIfAbsent(key, new Function<String, Class<?>>() {
+        if (classesNotFound.containsKey(key) || classesNotFoundExceptions.containsKey(key)) {
+            Exception e = classesNotFoundExceptions.get(key);
+            if (e == null) {
+                return null;
+            } else {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+        }
+
+        Class<?> suppliedClass = classMap.computeIfAbsent(key, new Function<String, Class<?>>() {
             @Override
             public Class<?> apply(String classKey) {
                 try {
                     return mappingFunction.get();
                 } catch (Exception e) {
+                    classesNotFoundExceptions.put(key, e);
                     throw RuntimeCamelException.wrapRuntimeException(e);
                 }
             }
         });
+
+        if (suppliedClass == null) {
+            // mark the key as non-resolvable to prevent pointless searching
+            classesNotFound.put(key, Boolean.TRUE);
+        }
+
+        return suppliedClass;
     }
 
     @FunctionalInterface
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultFactoryFinderTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultFactoryFinderTest.java
index 443b88b..615af00 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultFactoryFinderTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/DefaultFactoryFinderTest.java
@@ -31,6 +31,8 @@ import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 public class DefaultFactoryFinderTest {
@@ -64,6 +66,24 @@ public class DefaultFactoryFinderTest {
     }
 
     @Test
+    public void shouldCacheFailedAttemptToResolveClass() throws IOException {
+        final ClassResolver classResolver = mock(ClassResolver.class);
+
+        final String properties = "class=" + TestImplA.class.getName();
+
+        when(classResolver.loadResourceAsStream("/org/apache/camel/impl/TestImplA")).thenReturn(new ByteArrayInputStream(properties.getBytes()));
+
+        when(classResolver.resolveClass(TestImplA.class.getName())).thenReturn(null);
+
+        final DefaultFactoryFinder factoryFinder = new DefaultFactoryFinder(classResolver, TEST_RESOURCE_PATH);
+
+        assertFalse(factoryFinder.findClass("TestImplA").isPresent());
+        assertFalse(factoryFinder.findClass("TestImplA").isPresent());
+
+        verify(classResolver, times(1)).resolveClass(TestImplA.class.getName());
+    }
+
+    @Test
     public void shouldComplainIfInstanceTypeIsNotAsExpected() throws ClassNotFoundException, IOException {
         final Injector injector = mock(Injector.class);