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 2019/08/08 11:42:55 UTC

[camel] branch CAMEL-13837 created (now 077c581)

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

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


      at 077c581  CAMEL-13837: FactoryFinder API should avoid throwing exceptions for not found resoucces/classes and use Optional API instead. This avoids many try .. catch ignore exceptions during startup of Camel also.

This branch includes the following new commits:

     new 077c581  CAMEL-13837: FactoryFinder API should avoid throwing exceptions for not found resoucces/classes and use Optional API instead. This avoids many try .. catch ignore exceptions during startup of Camel also.

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-13837: FactoryFinder API should avoid throwing exceptions for not found resoucces/classes and use Optional API instead. This avoids many try .. catch ignore exceptions during startup of Camel also.

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

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

commit 077c581df65d24da0ed7561f69068ff9414d21e2
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Aug 8 13:42:32 2019 +0200

    CAMEL-13837: FactoryFinder API should avoid throwing exceptions for not found resoucces/classes and use Optional API instead. This avoids many try .. catch ignore exceptions during startup of Camel also.
---
 .../camel/component/file/GenericFileEndpoint.java  |   4 +-
 .../component/properties/PropertiesComponent.java  |   2 +-
 .../reactive/streams/ReactiveStreamsHelper.java    |  11 +-
 .../java/org/apache/camel/spi/FactoryFinder.java   |  31 +---
 .../impl/converter/BaseTypeConverterRegistry.java  |  52 +++++-
 .../camel/impl/engine/AbstractCamelContext.java    | 188 ++++++++-------------
 .../impl/engine/BeanProcessorFactoryResolver.java  |   4 +-
 .../impl/engine/BeanProxyFactoryResolver.java      |   4 +-
 .../impl/engine/DefaultComponentResolver.java      |   4 +-
 .../impl/engine/DefaultDataFormatResolver.java     |   6 +-
 .../camel/impl/engine/DefaultFactoryFinder.java    | 123 ++++----------
 .../camel/impl/engine/DefaultLanguageResolver.java |   4 +-
 .../camel/impl/engine/DefaultProcessorFactory.java |  14 +-
 .../impl/engine/HeadersMapFactoryResolver.java     |   4 +-
 .../impl/engine/ReactiveExecutorResolver.java      |   4 +-
 .../impl/engine/RestRegistryFactoryResolver.java   |   4 +-
 .../camel/processor/SendDynamicAwareResolver.java  |   4 +-
 .../impl/cloud/ServiceCallProcessorFactory.java    |   2 +-
 .../apache/camel/core/osgi/OsgiFactoryFinder.java  |  14 +-
 .../camel/core/osgi/OsgiFactoryFinderTest.java     |   6 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |   8 +-
 .../cloud/ServiceCallExpressionConfiguration.java  |   2 +-
 .../ServiceCallServiceChooserConfiguration.java    |   2 +-
 .../ServiceCallServiceDiscoveryConfiguration.java  |   2 +-
 .../ServiceCallServiceFilterConfiguration.java     |   2 +-
 ...erviceCallServiceLoadBalancerConfiguration.java |   2 +-
 .../impl/engine/DefaultFactoryFinderTest.java      |  62 ++-----
 27 files changed, 229 insertions(+), 336 deletions(-)

diff --git a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
index d41ed29..58aa43cf 100644
--- a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
+++ b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
@@ -277,9 +277,7 @@ public abstract class GenericFileEndpoint<T> extends ScheduledPollEndpoint imple
         try {
             FactoryFinder finder = getCamelContext().adapt(ExtendedCamelContext.class).getFactoryFinder("META-INF/services/org/apache/camel/component/");
             log.trace("Using FactoryFinder: {}", finder);
-            factory = finder.findClass(getScheme(), "strategy.factory.", CamelContext.class);
-        } catch (ClassNotFoundException e) {
-            log.trace("'strategy.factory.class' not found", e);
+            factory = finder.findClass(getScheme(), "strategy.factory.", CamelContext.class).orElse(null);
         } catch (IOException e) {
             log.trace("No strategy factory defined in 'META-INF/services/org/apache/camel/component/'", e);
         }
diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index 1492d62..a97f446 100644
--- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -462,7 +462,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
         // discover any 3rd party properties sources
         try {
             FactoryFinder factoryFinder = getCamelContext().adapt(ExtendedCamelContext.class).getFactoryFinder("META-INF/services/org/apache/camel");
-            Class<?> type = factoryFinder.findClass("properties-source-factory");
+            Class<?> type = factoryFinder.findClass("properties-source-factory").orElse(null);
             if (type != null) {
                 Object obj = getCamelContext().getInjector().newInstance(type, false);
                 if (obj instanceof PropertiesSource) {
diff --git a/components/camel-reactive-streams/src/main/java/org/apache/camel/component/reactive/streams/ReactiveStreamsHelper.java b/components/camel-reactive-streams/src/main/java/org/apache/camel/component/reactive/streams/ReactiveStreamsHelper.java
index 40f7b54..a380934 100644
--- a/components/camel-reactive-streams/src/main/java/org/apache/camel/component/reactive/streams/ReactiveStreamsHelper.java
+++ b/components/camel-reactive-streams/src/main/java/org/apache/camel/component/reactive/streams/ReactiveStreamsHelper.java
@@ -114,11 +114,12 @@ public final class ReactiveStreamsHelper {
     public static CamelReactiveStreamsServiceFactory resolveServiceFactory(CamelContext context, String serviceType) {
         try {
             FactoryFinder finder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(ReactiveStreamsConstants.SERVICE_PATH);
-            Class<?> serviceClass = finder.findClass(serviceType);
-
-            return (CamelReactiveStreamsServiceFactory)context.getInjector().newInstance(serviceClass);
-        } catch (ClassNotFoundException e) {
-            throw new IllegalStateException("Class referenced in '" + ReactiveStreamsConstants.SERVICE_PATH + serviceType + "' not found", e);
+            Class<?> serviceClass = finder.findClass(serviceType).orElse(null);
+            if (serviceClass != null) {
+                return (CamelReactiveStreamsServiceFactory) context.getInjector().newInstance(serviceClass);
+            } else {
+                throw new IllegalStateException("Class referenced in '" + ReactiveStreamsConstants.SERVICE_PATH + serviceType + "' not found");
+            }
         } catch (Exception e) {
             throw new IllegalStateException("Unable to create the reactive stream service defined in '" + ReactiveStreamsConstants.SERVICE_PATH + serviceType + "'", e);
         }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java b/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java
index 9d98628..a6ba2aa 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/FactoryFinder.java
@@ -16,10 +16,7 @@
  */
 package org.apache.camel.spi;
 
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.camel.NoFactoryAvailableException;
+import java.util.Optional;
 
 /**
  * Finder to find factories from the resource classpath, usually <b>META-INF/services/org/apache/camel/</b>.
@@ -37,32 +34,26 @@ public interface FactoryFinder {
      * Creates a new class instance using the key to lookup
      *
      * @param key is the key to add to the path to find a text file containing the factory name
-     * @return a newly created instance
-     * @throws org.apache.camel.NoFactoryAvailableException is thrown if no factories exist for the given key
+     * @return a newly created instance (if exists)
      */
-    Object newInstance(String key) throws NoFactoryAvailableException;
+    Optional<Object> newInstance(String key);
 
     /**
      * Creates a new class instance using the key to lookup
      *
      * @param key is the key to add to the path to find a text file containing the factory name
-     * @param injector injector to use
-     * @param type expected type
-     * @return a newly created instance as the expected type
-     * @throws ClassNotFoundException is thrown if not found
-     * @throws java.io.IOException is thrown if loading the class or META-INF file not found
+     * @param type the class type
+     * @return a newly created instance (if exists)
      */
-    <T> List<T> newInstances(String key, Injector injector, Class<T> type) throws ClassNotFoundException, IOException;
+    <T> Optional<T> newInstance(String key, Class<T> type);
 
     /**
      * Finds the given factory class using the key to lookup.
      *
      * @param key is the key to add to the path to find a text file containing the factory name
      * @return the factory class
-     * @throws ClassNotFoundException is thrown if class not found
-     * @throws java.io.IOException is thrown if loading the class or META-INF file not found
      */
-    Class<?> findClass(String key) throws ClassNotFoundException, IOException;
+    Optional<Class<?>> findClass(String key);
 
     /**
      * Finds the given factory class using the key to lookup.
@@ -70,10 +61,8 @@ public interface FactoryFinder {
      * @param key is the key to add to the path to find a text file containing the factory name
      * @param propertyPrefix prefix on key
      * @return the factory class
-     * @throws ClassNotFoundException is thrown if not found
-     * @throws java.io.IOException is thrown if loading the class or META-INF file not found
      */
-    Class<?> findClass(String key, String propertyPrefix) throws ClassNotFoundException, IOException;
+    Optional<Class<?>> findClass(String key, String propertyPrefix);
 
     /**
      * Finds the given factory class using the key to lookup.
@@ -82,8 +71,6 @@ public interface FactoryFinder {
      * @param propertyPrefix prefix on key
      * @param clazz the class which is used for checking compatible
      * @return the factory class
-     * @throws ClassNotFoundException is thrown if not found
-     * @throws java.io.IOException is thrown if loading the class or META-INF file not found
      */
-    Class<?> findClass(String key, String propertyPrefix, Class<?> clazz) throws ClassNotFoundException, IOException;
+    Optional<Class<?>> findClass(String key, String propertyPrefix, Class<?> clazz);
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
index 8dfce4c..f40b9fd 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
@@ -68,6 +68,7 @@ import org.apache.camel.util.ObjectHelper;
 public abstract class BaseTypeConverterRegistry extends ServiceSupport implements TypeConverter, TypeConverterRegistry {
 
     public static final String META_INF_SERVICES_TYPE_CONVERTER_LOADER = "META-INF/services/org/apache/camel/TypeConverterLoader";
+    public static final String META_INF_SERVICES_FALLBACK_TYPE_CONVERTER = "META-INF/services/org/apache/camel/FallbackTypeConverter";
 
     protected static final TypeConverter MISS_CONVERTER = new TypeConverterSupport() {
         @Override
@@ -587,11 +588,54 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement
         }
     }
 
+    /**
+     * Finds the fallback type converter classes from the classpath looking
+     * for text files on the classpath at the {@link #META_INF_SERVICES_FALLBACK_TYPE_CONVERTER} location.
+     */
+    protected Collection<String> findFallbackTypeConverterClasses() throws IOException {
+        Set<String> loaders = new LinkedHashSet<>();
+        Collection<URL> loaderResources = getFallbackUrls();
+        for (URL url : loaderResources) {
+            log.debug("Loading file {} to retrieve list of fallback type converters, from url: {}", META_INF_SERVICES_FALLBACK_TYPE_CONVERTER, url);
+            BufferedReader reader = IOHelper.buffered(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
+            try {
+                reader.lines()
+                        .map(String::trim)
+                        .filter(l -> !l.isEmpty())
+                        .filter(l -> !l.startsWith("#"))
+                        .forEach(loaders::add);
+            } finally {
+                IOHelper.close(reader, url.toString(), log);
+            }
+        }
+        return loaders;
+    }
+
+    protected Collection<URL> getFallbackUrls() throws IOException {
+        List<URL> loaderResources = new ArrayList<>();
+        for (ClassLoader classLoader : resolver.getClassLoaders()) {
+            Enumeration<URL> resources = classLoader.getResources(META_INF_SERVICES_FALLBACK_TYPE_CONVERTER);
+            while (resources.hasMoreElements()) {
+                URL url = resources.nextElement();
+                loaderResources.add(url);
+            }
+        }
+        return loaderResources;
+    }
+
     protected void loadFallbackTypeConverters() throws IOException, ClassNotFoundException {
-        if (factoryFinder != null) {
-            List<TypeConverter> converters = factoryFinder.newInstances("FallbackTypeConverter", getInjector(), TypeConverter.class);
-            for (TypeConverter converter : converters) {
-                addFallbackTypeConverter(converter, false);
+        Collection<String> names = findFallbackTypeConverterClasses();
+        for (String name : names) {
+            log.debug("Resolving FallbackTypeConverter: {}", name);
+            Class clazz = getResolver().getClassLoaders().stream()
+                    .map(cl -> ObjectHelper.loadClass(name, cl))
+                    .filter(Objects::nonNull)
+                    .findAny().orElseThrow(() -> new ClassNotFoundException(name));
+            Object obj = getInjector().newInstance(clazz, false);
+            if (obj instanceof TypeConverter) {
+                TypeConverter fb = (TypeConverter) obj;
+                log.debug("Adding loaded FallbackTypeConverter: {}", name);
+                addFallbackTypeConverter(fb, false);
             }
         }
     }
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 29e2fdf..20a6723 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
@@ -1499,46 +1499,35 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
         // component class, which is the location
         // where the documentation exists as well
         FactoryFinder finder = getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH);
-        try {
-            Class<?> clazz = null;
-            try {
-                clazz = finder.findClass(componentName);
-            } catch (NoFactoryAvailableException e) {
-                // ignore, i.e. if a component is an auto-configured spring-boot
-                // component
-            }
-
-            if (clazz == null) {
-                // fallback and find existing component
-                Component existing = hasComponent(componentName);
-                if (existing != null) {
-                    clazz = existing.getClass();
-                } else {
-                    return null;
-                }
+        Class<?> clazz = finder.findClass(componentName).orElse(null);
+        if (clazz == null) {
+            // fallback and find existing component
+            Component existing = hasComponent(componentName);
+            if (existing != null) {
+                clazz = existing.getClass();
+            } else {
+                return null;
             }
+        }
 
-            String packageName = clazz.getPackage().getName();
-            packageName = packageName.replace('.', '/');
-            String path = packageName + "/" + componentName + ".json";
+        String packageName = clazz.getPackage().getName();
+        packageName = packageName.replace('.', '/');
+        String path = packageName + "/" + componentName + ".json";
 
-            ClassResolver resolver = getClassResolver();
-            InputStream inputStream = resolver.loadResourceAsStream(path);
-            log.debug("Loading component JSON Schema for: {} using class resolver: {} -> {}", componentName, resolver, inputStream);
-            if (inputStream != null) {
-                try {
-                    return IOHelper.loadText(inputStream);
-                } finally {
-                    IOHelper.close(inputStream);
-                }
-            }
-            // special for ActiveMQ as it is really just JMS
-            if ("ActiveMQComponent".equals(clazz.getSimpleName())) {
-                return getComponentParameterJsonSchema("jms");
-            } else {
-                return null;
+        ClassResolver resolver = getClassResolver();
+        InputStream inputStream = resolver.loadResourceAsStream(path);
+        log.debug("Loading component JSON Schema for: {} using class resolver: {} -> {}", componentName, resolver, inputStream);
+        if (inputStream != null) {
+            try {
+                return IOHelper.loadText(inputStream);
+            } finally {
+                IOHelper.close(inputStream);
             }
-        } catch (ClassNotFoundException e) {
+        }
+        // special for ActiveMQ as it is really just JMS
+        if ("ActiveMQComponent".equals(clazz.getSimpleName())) {
+            return getComponentParameterJsonSchema("jms");
+        } else {
             return null;
         }
     }
@@ -1548,38 +1537,26 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
         // dataformat class, which is the location
         // where the documentation exists as well
         FactoryFinder finder = getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH);
-        try {
-            Class<?> clazz = null;
-            try {
-                clazz = finder.findClass(dataFormatName);
-            } catch (NoFactoryAvailableException e) {
-                // ignore, i.e. if a component is an auto-configured spring-boot
-                // data-formats
-            }
-
-            if (clazz == null) {
-                return null;
-            }
+        Class<?> clazz = finder.findClass(dataFormatName).orElse(null);
+        if (clazz == null) {
+            return null;
+        }
 
-            String packageName = clazz.getPackage().getName();
-            packageName = packageName.replace('.', '/');
-            String path = packageName + "/" + dataFormatName + ".json";
+        String packageName = clazz.getPackage().getName();
+        packageName = packageName.replace('.', '/');
+        String path = packageName + "/" + dataFormatName + ".json";
 
-            ClassResolver resolver = getClassResolver();
-            InputStream inputStream = resolver.loadResourceAsStream(path);
-            log.debug("Loading dataformat JSON Schema for: {} using class resolver: {} -> {}", dataFormatName, resolver, inputStream);
-            if (inputStream != null) {
-                try {
-                    return IOHelper.loadText(inputStream);
-                } finally {
-                    IOHelper.close(inputStream);
-                }
+        ClassResolver resolver = getClassResolver();
+        InputStream inputStream = resolver.loadResourceAsStream(path);
+        log.debug("Loading dataformat JSON Schema for: {} using class resolver: {} -> {}", dataFormatName, resolver, inputStream);
+        if (inputStream != null) {
+            try {
+                return IOHelper.loadText(inputStream);
+            } finally {
+                IOHelper.close(inputStream);
             }
-            return null;
-
-        } catch (ClassNotFoundException e) {
-            return null;
         }
+        return null;
     }
 
     public String getLanguageParameterJsonSchema(String languageName) throws IOException {
@@ -1587,38 +1564,26 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
         // language class, which is the location
         // where the documentation exists as well
         FactoryFinder finder = getFactoryFinder(DefaultLanguageResolver.LANGUAGE_RESOURCE_PATH);
-        try {
-            Class<?> clazz = null;
-            try {
-                clazz = finder.findClass(languageName);
-            } catch (NoFactoryAvailableException e) {
-                // ignore, i.e. if a component is an auto-configured spring-boot
-                // languages
-            }
-
-            if (clazz == null) {
-                return null;
-            }
+        Class<?> clazz = finder.findClass(languageName).orElse(null);
+        if (clazz == null) {
+            return null;
+        }
 
-            String packageName = clazz.getPackage().getName();
-            packageName = packageName.replace('.', '/');
-            String path = packageName + "/" + languageName + ".json";
+        String packageName = clazz.getPackage().getName();
+        packageName = packageName.replace('.', '/');
+        String path = packageName + "/" + languageName + ".json";
 
-            ClassResolver resolver = getClassResolver();
-            InputStream inputStream = resolver.loadResourceAsStream(path);
-            log.debug("Loading language JSON Schema for: {} using class resolver: {} -> {}", languageName, resolver, inputStream);
-            if (inputStream != null) {
-                try {
-                    return IOHelper.loadText(inputStream);
-                } finally {
-                    IOHelper.close(inputStream);
-                }
+        ClassResolver resolver = getClassResolver();
+        InputStream inputStream = resolver.loadResourceAsStream(path);
+        log.debug("Loading language JSON Schema for: {} using class resolver: {} -> {}", languageName, resolver, inputStream);
+        if (inputStream != null) {
+            try {
+                return IOHelper.loadText(inputStream);
+            } finally {
+                IOHelper.close(inputStream);
             }
-            return null;
-
-        } catch (ClassNotFoundException e) {
-            return null;
         }
+        return null;
     }
 
     public String getEipParameterJsonSchema(String eipName) throws IOException {
@@ -3444,21 +3409,20 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
             Object comp = ResolverHelper.lookupComponentInRegistryWithFallback(this, "properties");
             if (comp == null) {
                 try {
-                    Class<?> type = getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH).findClass("properties");
-                    if (type != null) {
-                        log.debug("No existing PropertiesComponent has been configured, creating a new default PropertiesComponent with name: properties");
-                        comp = type.getDeclaredConstructor().newInstance();
-                        globalOptions.put(PropertiesComponent.DEFAULT_CREATED, "true");
-                    }
-                } catch (Exception e) {
-                    throw new IllegalArgumentException("No Component registered for scheme: " + "properties", e);
+                    comp = getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH).newInstance("properties").orElse(null);
+                } catch (NoFactoryAvailableException e) {
+                    // ignore
+                }
+                if (comp != null) {
+                    log.debug("No existing PropertiesComponent has been configured, created a new default PropertiesComponent with name: properties");
+                    globalOptions.put(PropertiesComponent.DEFAULT_CREATED, "true");
+                }
+                if (comp instanceof PropertiesComponent) {
+                    addComponent("properties", (PropertiesComponent) comp);
+                }
+                if (propertiesComponent == null) {
+                    throw new IllegalStateException("Cannot auto create Properties component");
                 }
-            }
-            if (comp instanceof PropertiesComponent) {
-                addComponent("properties", (PropertiesComponent)comp);
-            }
-            if (propertiesComponent == null) {
-                throw new IllegalStateException();
             }
         }
         return propertiesComponent;
@@ -3624,15 +3588,11 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
         if (!isJMXDisabled()) {
             try {
                 FactoryFinder finder = getFactoryFinder("META-INF/services/org/apache/camel/management/");
-                try {
-                    if (finder != null) {
-                        Object object = finder.newInstance("ManagementStrategyFactory");
-                        if (object instanceof ManagementStrategyFactory) {
-                            factory = (ManagementStrategyFactory)object;
-                        }
+                if (finder != null) {
+                    Object object = finder.newInstance("ManagementStrategyFactory").orElse(null);
+                    if (object instanceof ManagementStrategyFactory) {
+                        factory = (ManagementStrategyFactory)object;
                     }
-                } catch (NoFactoryAvailableException e) {
-                    // ignore there is no custom factory
                 }
             } catch (Exception e) {
                 log.warn("Cannot create JMX lifecycle strategy. Will fallback and disable JMX.", e);
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProcessorFactoryResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProcessorFactoryResolver.java
index cc9f375..f0e1c91 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProcessorFactoryResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProcessorFactoryResolver.java
@@ -62,11 +62,11 @@ public class BeanProcessorFactoryResolver {
         return null;
     }
 
-    private Class<?> findFactory(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findFactory(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProxyFactoryResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProxyFactoryResolver.java
index 39405f6..6fda9ed 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProxyFactoryResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/BeanProxyFactoryResolver.java
@@ -62,11 +62,11 @@ public class BeanProxyFactoryResolver {
         return null;
     }
 
-    private Class<?> findFactory(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findFactory(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultComponentResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultComponentResolver.java
index 35f0eaf..cb4484d 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultComponentResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultComponentResolver.java
@@ -76,11 +76,11 @@ public class DefaultComponentResolver implements ComponentResolver {
         }
     }
 
-    private Class<?> findComponent(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findComponent(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
     protected Logger getLog() {
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultDataFormatResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultDataFormatResolver.java
index 1d7f3a9..ed044f1 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultDataFormatResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultDataFormatResolver.java
@@ -67,14 +67,12 @@ public class DefaultDataFormatResolver implements DataFormatResolver {
     private DataFormat createDataFormatFromResource(String name, CamelContext context) {
         DataFormat dataFormat = null;
 
-        Class<?> type = null;
+        Class<?> type;
         try {
             if (dataformatFactory == null) {
                 dataformatFactory = context.adapt(ExtendedCamelContext.class).getFactoryFinder(DATAFORMAT_RESOURCE_PATH);
             }
-            type = dataformatFactory.findClass(name);
-        } catch (NoFactoryAvailableException e) {
-            // ignore
+            type = dataformatFactory.findClass(name).orElse(null);
         } catch (Exception e) {
             throw new IllegalArgumentException("Invalid URI, no DataFormat registered for scheme: " + name, e);
         }
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 d604cfa..ae97d77 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
@@ -19,19 +19,16 @@ package org.apache.camel.impl.engine;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
 
-import org.apache.camel.NoFactoryAvailableException;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.FactoryFinder;
-import org.apache.camel.spi.Injector;
-import org.apache.camel.util.CastUtils;
+import org.apache.camel.support.ObjectHelper;
 import org.apache.camel.util.IOHelper;
 
 /**
@@ -54,87 +51,56 @@ public class DefaultFactoryFinder implements FactoryFinder {
     }
 
     @Override
-    public Object newInstance(String key) throws NoFactoryAvailableException {
-        try {
-            return newInstance(key, null);
-        } catch (Exception e) {
-            throw new NoFactoryAvailableException(key, e);
-        }
+    public Optional<Object> newInstance(String key) {
+        return Optional.ofNullable(doNewInstance(key, null));
     }
 
     @Override
-    public <T> List<T> newInstances(String key, Injector injector, Class<T> type) throws ClassNotFoundException, IOException {
-        List<Class<T>> list = CastUtils.cast(findClasses(key));
-        List<T> answer = new ArrayList<>(list.size());
-        answer.add(newInstance(key, injector, type));
-        return answer;
+    public <T> Optional<T> newInstance(String key, Class<T> type) {
+        Object obj = doNewInstance(key, null);
+        return Optional.ofNullable(type.cast(obj));
     }
 
     @Override
-    public Class<?> findClass(String key) throws ClassNotFoundException, IOException {
+    public Optional<Class<?>> findClass(String key) {
         return findClass(key, null);
     }
 
     @Override
-    public Class<?> findClass(String key, String propertyPrefix) throws ClassNotFoundException, IOException {
+    public Optional<Class<?>> findClass(String key, String propertyPrefix) {
         final String prefix = propertyPrefix != null ? propertyPrefix : "";
         final String classKey = prefix + key;
 
-        return addToClassMap(classKey, new ClassSupplier() {
-            @Override
-            public Class<?> get() throws ClassNotFoundException, IOException {
-                return DefaultFactoryFinder.this.newInstance(DefaultFactoryFinder.this.doFindFactoryProperties(key), prefix);
+        Class<?> clazz = addToClassMap(classKey, () -> {
+            Properties prop = doFindFactoryProperties(key);
+            if (prop != null) {
+                return doNewInstance(prop, prefix).orElse(null);
+            } else {
+                return null;
             }
         });
+        return Optional.ofNullable(clazz);
     }
 
     @Override
-    public Class<?> findClass(String key, String propertyPrefix, Class<?> clazz) throws ClassNotFoundException, IOException {
+    public Optional<Class<?>> findClass(String key, String propertyPrefix, Class<?> clazz) {
         // Just ignore clazz which is only useful for OSGiFactoryFinder
         return findClass(key, propertyPrefix);
     }
 
-    private Object newInstance(String key, String propertyPrefix) throws Exception {
-        Class<?> clazz = findClass(key, propertyPrefix);
-        return clazz.getDeclaredConstructor().newInstance();
-    }
-
-    private <T> T newInstance(String key, Injector injector, Class<T> expectedType) throws IOException,
-        ClassNotFoundException {
-        return newInstance(key, injector, null, expectedType);
-    }
-
-    private <T> T newInstance(String key, Injector injector, String propertyPrefix, Class<T> expectedType)
-        throws IOException, ClassNotFoundException {
-        Class<?> type = findClass(key, propertyPrefix);
-        Object value = injector.newInstance(type, false);
-        if (expectedType.isInstance(value)) {
-            return expectedType.cast(value);
-        } else {
-            throw new ClassCastException("Not instanceof " + expectedType.getName() + " value: " + value);
-        }
-    }
-
-    private List<Class<?>> findClasses(String key) throws ClassNotFoundException, IOException {
-        return findClasses(key, null);
+    private Object doNewInstance(String key, String propertyPrefix) {
+        Optional<Class<?>> clazz = findClass(key, propertyPrefix);
+        return clazz.map(ObjectHelper::newInstance).orElse(null);
     }
 
-    private List<Class<?>> findClasses(String key, String propertyPrefix) throws ClassNotFoundException, IOException {
-        Class<?> type = findClass(key, propertyPrefix);
-        return Collections.<Class<?>>singletonList(type);
-    }
-
-    private Class<?> newInstance(Properties properties, String propertyPrefix) throws ClassNotFoundException, IOException {
+    private Optional<Class<?>> doNewInstance(Properties properties, String propertyPrefix) throws IOException {
         String className = properties.getProperty(propertyPrefix + "class");
         if (className == null) {
             throw new IOException("Expected property is missing: " + propertyPrefix + "class");
         }
 
         Class<?> clazz = classResolver.resolveClass(className);
-        if (clazz == null) {
-            throw new ClassNotFoundException(className);
-        }
-        return clazz;
+        return Optional.ofNullable(clazz);
     }
 
     private Properties doFindFactoryProperties(String key) throws IOException {
@@ -142,7 +108,7 @@ public class DefaultFactoryFinder implements FactoryFinder {
 
         InputStream in = classResolver.loadResourceAsStream(uri);
         if (in == null) {
-            throw new NoFactoryAvailableException(uri);
+            return null;
         }
 
         // lets load the file
@@ -163,43 +129,22 @@ public class DefaultFactoryFinder implements FactoryFinder {
      * is wrapped by a runtime exception (WrappedRuntimeException) which we catch
      * later on with the only purpose to re-throw the original exception.
      */
-    protected Class<?> addToClassMap(String key, ClassSupplier mappingFunction) throws ClassNotFoundException, IOException {
-        try {
-            return classMap.computeIfAbsent(key, new Function<String, Class<?>>() {
-                @Override
-                public Class<?> apply(String classKey) {
-                    try {
-                        return mappingFunction.get();
-                    } catch (ClassNotFoundException e) {
-                        throw new WrappedRuntimeException(e);
-                    } catch (NoFactoryAvailableException e) {
-                        throw new WrappedRuntimeException(e);
-                    } catch (IOException e) {
-                        throw new WrappedRuntimeException(e);
-                    }
+    protected Class<?> addToClassMap(String key, ClassSupplier mappingFunction) {
+        return classMap.computeIfAbsent(key, new Function<String, Class<?>>() {
+            @Override
+            public Class<?> apply(String classKey) {
+                try {
+                    return mappingFunction.get();
+                } catch (Exception e) {
+                    throw RuntimeCamelException.wrapRuntimeException(e);
                 }
-            });
-        } catch (WrappedRuntimeException e) {
-            if (e.getCause() instanceof ClassNotFoundException) {
-                throw (ClassNotFoundException)e.getCause();
-            } else if (e.getCause() instanceof NoFactoryAvailableException) {
-                throw (NoFactoryAvailableException)e.getCause();
-            } else if (e.getCause() instanceof IOException) {
-                throw (IOException)e.getCause();
-            } else {
-                throw new RuntimeException(e.getCause());
             }
-        }
+        });
     }
 
     @FunctionalInterface
     protected interface ClassSupplier {
-        Class<?> get() throws ClassNotFoundException, IOException;
+        Class<?> get() throws Exception;
     }
 
-    private final class WrappedRuntimeException extends RuntimeException {
-        WrappedRuntimeException(Exception e) {
-            super(e);
-        }
-    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultLanguageResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultLanguageResolver.java
index b3c0aa1..61486f5 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultLanguageResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultLanguageResolver.java
@@ -96,14 +96,14 @@ public class DefaultLanguageResolver implements LanguageResolver {
         if (languageFactory == null) {
             languageFactory = context.adapt(ExtendedCamelContext.class).getFactoryFinder(LANGUAGE_RESOURCE_PATH);
         }
-        return languageFactory.findClass(name);
+        return languageFactory.findClass(name).orElse(null);
     }
 
     protected Class<?> findLanguageResolver(String name, CamelContext context) throws Exception {
         if (languageResolver == null) {
             languageResolver = context.adapt(ExtendedCamelContext.class).getFactoryFinder(LANGUAGE_RESOLVER_RESOURCE_PATH);
         }
-        return languageResolver.findClass(name);
+        return languageResolver.findClass(name).orElse(null);
     }
 
     protected Logger getLog() {
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProcessorFactory.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProcessorFactory.java
index f31e7a2..7be64cb 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProcessorFactory.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProcessorFactory.java
@@ -31,6 +31,7 @@ import org.apache.camel.processor.UnitOfWorkProducer;
 import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.ProcessorFactory;
 import org.apache.camel.spi.RouteContext;
+import org.apache.camel.support.ObjectHelper;
 
 /**
  * Default {@link ProcessorFactory} that supports using 3rd party Camel components to implement the EIP {@link Processor}.
@@ -70,16 +71,11 @@ public class DefaultProcessorFactory implements ProcessorFactory {
     public Processor createProcessor(RouteContext routeContext, NamedNode definition) throws Exception {
         String name = definition.getClass().getSimpleName();
         FactoryFinder finder = routeContext.getCamelContext().adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
-        try {
-            if (finder != null) {
-                Object object = finder.newInstance(name);
-                if (object instanceof ProcessorFactory) {
-                    ProcessorFactory pc = (ProcessorFactory) object;
-                    return pc.createProcessor(routeContext, definition);
-                }
+        if (finder != null) {
+            ProcessorFactory pc = finder.newInstance(name, ProcessorFactory.class).orElse(null);
+            if (pc != null) {
+                return pc.createProcessor(routeContext, definition);
             }
-        } catch (NoFactoryAvailableException e) {
-            // ignore there is no custom factory
         }
 
         return null;
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/HeadersMapFactoryResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/HeadersMapFactoryResolver.java
index 0a8e72d..d775765 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/HeadersMapFactoryResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/HeadersMapFactoryResolver.java
@@ -65,11 +65,11 @@ public class HeadersMapFactoryResolver {
         return new DefaultHeadersMapFactory();
     }
 
-    private Class<?> findFactory(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findFactory(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/ReactiveExecutorResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/ReactiveExecutorResolver.java
index b5a2d03..378bc9d 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/ReactiveExecutorResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/ReactiveExecutorResolver.java
@@ -63,11 +63,11 @@ public class ReactiveExecutorResolver {
         return new DefaultReactiveExecutor();
     }
 
-    private Class<?> findFactory(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findFactory(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/RestRegistryFactoryResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/RestRegistryFactoryResolver.java
index a63263b..162f9e5 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/RestRegistryFactoryResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/RestRegistryFactoryResolver.java
@@ -64,11 +64,11 @@ public class RestRegistryFactoryResolver {
         return null;
     }
 
-    private Class<?> findFactory(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findFactory(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java b/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java
index c221bae..6bbefea 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/SendDynamicAwareResolver.java
@@ -60,11 +60,11 @@ public class SendDynamicAwareResolver {
         return null;
     }
 
-    private Class<?> findFactory(String name, CamelContext context) throws ClassNotFoundException, IOException {
+    private Class<?> findFactory(String name, CamelContext context) throws IOException {
         if (factoryFinder == null) {
             factoryFinder = context.adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH);
         }
-        return factoryFinder.findClass(name);
+        return factoryFinder.findClass(name).orElse(null);
     }
 
 }
diff --git a/core/camel-cloud/src/main/java/org/apache/camel/impl/cloud/ServiceCallProcessorFactory.java b/core/camel-cloud/src/main/java/org/apache/camel/impl/cloud/ServiceCallProcessorFactory.java
index fb4e5b4..0aab58c 100644
--- a/core/camel-cloud/src/main/java/org/apache/camel/impl/cloud/ServiceCallProcessorFactory.java
+++ b/core/camel-cloud/src/main/java/org/apache/camel/impl/cloud/ServiceCallProcessorFactory.java
@@ -384,7 +384,7 @@ public class ServiceCallProcessorFactory extends TypedProcessorFactory<ServiceCa
 
                 try {
                     // Then use Service factory.
-                    type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(lookupName);
+                    type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(lookupName).orElse(null);
                 } catch (Exception e) {
                 }
 
diff --git a/core/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiFactoryFinder.java b/core/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiFactoryFinder.java
index cb03336..ba57b23 100644
--- a/core/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiFactoryFinder.java
+++ b/core/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiFactoryFinder.java
@@ -20,9 +20,9 @@ import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.Optional;
 import java.util.Properties;
 
-import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.impl.engine.DefaultFactoryFinder;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.util.IOHelper;
@@ -44,11 +44,11 @@ public class OsgiFactoryFinder extends DefaultFactoryFinder {
     }
 
     @Override
-    public Class<?> findClass(String key, String propertyPrefix, Class<?> checkClass) throws ClassNotFoundException, IOException {
+    public Optional<Class<?>> findClass(String key, String propertyPrefix, Class<?> checkClass) {
         final String prefix = propertyPrefix != null ? propertyPrefix : "";
         final String classKey = propertyPrefix + key;
 
-        return addToClassMap(classKey, () -> {
+        Class<?> answer = addToClassMap(classKey, () -> {
             BundleEntry entry = getResource(key, checkClass);
             if (entry != null) {
                 URL url = entry.url;
@@ -69,13 +69,15 @@ public class OsgiFactoryFinder extends DefaultFactoryFinder {
                     IOHelper.close(in, key, null);
                 }
             } else {
-                throw new NoFactoryAvailableException(classKey);
+                return null;
             }
         });
+
+        return Optional.ofNullable(answer);
     }
 
     @Override
-    public Class<?> findClass(String key, String propertyPrefix) throws ClassNotFoundException, IOException {
+    public Optional<Class<?>> findClass(String key, String propertyPrefix) {
         return findClass(key, propertyPrefix, null);
     }
 
@@ -89,7 +91,7 @@ public class OsgiFactoryFinder extends DefaultFactoryFinder {
     // The clazz can make sure we get right version of class that we need
     public BundleEntry getResource(String name, Class<?> clazz) {
         BundleEntry entry = null;
-        Bundle[] bundles = null; 
+        Bundle[] bundles;
         
         bundles = bundleContext.getBundles();
         
diff --git a/core/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/OsgiFactoryFinderTest.java b/core/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/OsgiFactoryFinderTest.java
index e245f44..b38ab3e 100644
--- a/core/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/OsgiFactoryFinderTest.java
+++ b/core/camel-core-osgi/src/test/java/org/apache/camel/core/osgi/OsgiFactoryFinderTest.java
@@ -27,18 +27,18 @@ public class OsgiFactoryFinderTest extends CamelOsgiTestSupport {
     @Test
     public void testFindClass() throws Exception {
         OsgiFactoryFinder finder = new OsgiFactoryFinder(getBundleContext(), new DefaultClassResolver(), "META-INF/services/org/apache/camel/component/");
-        Class<?> clazz = finder.findClass("file_test", "strategy.factory.");
+        Class<?> clazz = finder.findClass("file_test", "strategy.factory.").orElse(null);
         assertNotNull("We should get the file strategy factory here", clazz);
         
         try {
-            clazz = finder.findClass("nofile", "strategy.factory.");
+            finder.findClass("nofile", "strategy.factory.");
             fail("We should get exception here");
         } catch (Exception ex) {
             assertTrue("Should get NoFactoryAvailableException", ex instanceof NoFactoryAvailableException);
         }
         
         try {
-            clazz = finder.findClass("file_test", "nostrategy.factory.");
+            finder.findClass("file_test", "nostrategy.factory.");
             fail("We should get exception here");
         } catch (Exception ex) {
             assertTrue("Should get IOException", ex instanceof IOException);
diff --git a/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 13d5df9..bb79975 100644
--- a/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -21,7 +21,6 @@ import javax.naming.Context;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
-import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.PollingConsumer;
 import org.apache.camel.Producer;
 import org.apache.camel.TypeConverter;
@@ -172,12 +171,7 @@ public class DefaultCamelContext extends AbstractModelCamelContext {
     @Override
     protected Injector createInjector() {
         FactoryFinder finder = getDefaultFactoryFinder();
-        try {
-            return (Injector) finder.newInstance("Injector");
-        } catch (NoFactoryAvailableException e) {
-            // lets use the default injector
-            return new DefaultInjector(this);
-        }
+        return finder.newInstance("Injector", Injector.class).orElse(new DefaultInjector(this));
     }
 
     @Override
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallExpressionConfiguration.java b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallExpressionConfiguration.java
index 0cd2d61..61ef0d1 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallExpressionConfiguration.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallExpressionConfiguration.java
@@ -228,7 +228,7 @@ public class ServiceCallExpressionConfiguration extends IdentifiedType implement
                 Class<?> type;
                 try {
                     // Then use Service factory.
-                    type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey);
+                    type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey).orElse(null);
                 } catch (Exception e) {
                     throw new NoFactoryAvailableException(ServiceCallDefinitionConstants.RESOURCE_PATH + factoryKey, e);
                 }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceChooserConfiguration.java b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceChooserConfiguration.java
index b3ff1b6..5b2c2d5 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceChooserConfiguration.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceChooserConfiguration.java
@@ -146,7 +146,7 @@ public class ServiceCallServiceChooserConfiguration extends IdentifiedType imple
             Class<?> type;
             try {
                 // Then use Service factory.
-                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey);
+                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey).orElse(null);
             } catch (Exception e) {
                 throw new NoFactoryAvailableException(ServiceCallDefinitionConstants.RESOURCE_PATH + factoryKey, e);
             }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
index f9ad9bd..3203420 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
@@ -153,7 +153,7 @@ public class ServiceCallServiceDiscoveryConfiguration extends IdentifiedType imp
             Class<?> type;
             try {
                 // Then use Service factory.
-                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey);
+                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey).orElse(null);
             } catch (Exception e) {
                 throw new NoFactoryAvailableException(ServiceCallDefinitionConstants.RESOURCE_PATH + factoryKey, e);
             }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceFilterConfiguration.java b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceFilterConfiguration.java
index 7a36a9c..cb14348 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceFilterConfiguration.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceFilterConfiguration.java
@@ -146,7 +146,7 @@ public class ServiceCallServiceFilterConfiguration extends IdentifiedType implem
             Class<?> type;
             try {
                 // Then use Service factory.
-                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey);
+                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey).orElse(null);
             } catch (Exception e) {
                 throw new NoFactoryAvailableException(ServiceCallDefinitionConstants.RESOURCE_PATH + factoryKey, e);
             }
diff --git a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceLoadBalancerConfiguration.java b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceLoadBalancerConfiguration.java
index d224f1f..d31fecbb 100644
--- a/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceLoadBalancerConfiguration.java
+++ b/core/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceLoadBalancerConfiguration.java
@@ -146,7 +146,7 @@ public class ServiceCallServiceLoadBalancerConfiguration extends IdentifiedType
             Class<?> type;
             try {
                 // Then use Service factory.
-                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey);
+                type = camelContext.adapt(ExtendedCamelContext.class).getFactoryFinder(ServiceCallDefinitionConstants.RESOURCE_PATH).findClass(factoryKey).orElse(null);
             } catch (Exception e) {
                 throw new NoFactoryAvailableException(ServiceCallDefinitionConstants.RESOURCE_PATH + factoryKey, e);
             }
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 bdaa0c3..6da11b2 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
@@ -19,19 +19,16 @@ package org.apache.camel.impl.engine;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.URL;
-import java.util.List;
 
-import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.Injector;
 import org.junit.Test;
 
-import static org.hamcrest.Matchers.matchesPattern;
-import static org.hamcrest.core.IsCollectionContaining.hasItem;
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertFalse;
 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.when;
@@ -64,13 +61,7 @@ public class DefaultFactoryFinderTest {
 
         final DefaultFactoryFinder factoryFinder = new DefaultFactoryFinder(classResolver, TEST_RESOURCE_PATH);
 
-        try {
-            factoryFinder.findClass("TestImplA", null);
-            fail("Should have thrown ClassNotFoundException");
-        } catch (final ClassNotFoundException e) {
-            assertEquals(TestImplA.class.getName(), e.getMessage());
-        }
-
+        assertFalse(factoryFinder.findClass("TestImplA", null).isPresent());
     }
 
     @Test
@@ -81,24 +72,16 @@ public class DefaultFactoryFinderTest {
         when(injector.newInstance(TestImplA.class, false)).thenReturn(expected);
 
         try {
-            factoryFinder.newInstances("TestImplA", injector, TestImplB.class);
-            fail("ClassCastException should have been thrown");
-        } catch (final ClassCastException e) {
-            final String message = e.getMessage();
-            assertThat(message,
-                    matchesPattern("Not instanceof org\\.apache\\.camel\\.impl\\.engine\\.DefaultFactoryFinderTest\\$TestImplB "
-                        + "value: org\\.apache\\.camel\\.impl\\.engine\\.DefaultFactoryFinderTest\\$TestImplA.*"));
+            factoryFinder.newInstance("TestImplA", TestImplB.class);
+            fail("Exception should have been thrown");
+        } catch (Exception e) {
+            assertTrue(e instanceof ClassCastException);
         }
     }
 
     @Test
     public void shouldComplainIfUnableToCreateNewInstances() throws ClassNotFoundException, IOException {
-        try {
-            factoryFinder.newInstance("TestImplX");
-            fail("NoFactoryAvailableException should have been thrown");
-        } catch (final NoFactoryAvailableException e) {
-            assertEquals("Cannot find factory class for resource: TestImplX", e.getMessage());
-        }
+        assertFalse(factoryFinder.newInstance("TestImplX").isPresent());
     }
 
     @Test
@@ -106,36 +89,21 @@ public class DefaultFactoryFinderTest {
         try {
             factoryFinder.findClass("TestImplNoProperty");
             fail("NoFactoryAvailableException should have been thrown");
-        } catch (final IOException e) {
-            assertEquals("Expected property is missing: class", e.getMessage());
+        } catch (Exception e) {
+            assertEquals("Expected property is missing: class", e.getCause().getMessage());
         }
     }
 
     @Test
     public void shouldCreateNewInstances() throws ClassNotFoundException, IOException {
-        final Object instance = factoryFinder.newInstance("TestImplA");
+        final Object instance = factoryFinder.newInstance("TestImplA").get();
 
         assertThat(instance, instanceOf(TestImplA.class));
     }
 
     @Test
-    public void shouldCreateNewInstancesWithInjector() throws ClassNotFoundException, IOException {
-        final Injector injector = mock(Injector.class);
-
-        final TestImplA expected = new TestImplA();
-        when(injector.newInstance(TestImplA.class, false)).thenReturn(expected);
-
-        final List<TestType> instances = factoryFinder.newInstances("TestImplA", injector, TestType.class);
-
-        assertEquals(1, instances.size());
-        assertThat(instances, hasItem(expected));
-
-        assertSame(expected, instances.get(0));
-    }
-
-    @Test
     public void shouldFindSingleClass() throws ClassNotFoundException, IOException {
-        final Class<?> clazz = factoryFinder.findClass("TestImplA");
+        final Class<?> clazz = factoryFinder.findClass("TestImplA").orElse(null);
 
         assertEquals(TestImplA.class, clazz);
     }
@@ -145,21 +113,21 @@ public class DefaultFactoryFinderTest {
         final DefaultFactoryFinder factoryFinder = new DefaultFactoryFinder(null, null);
         factoryFinder.addToClassMap("prefixkey", () -> TestImplA.class);
 
-        final Class<?> clazz = factoryFinder.findClass("key", "prefix");
+        final Class<?> clazz = factoryFinder.findClass("key", "prefix").orElse(null);
 
         assertEquals(TestImplA.class, clazz);
     }
 
     @Test
     public void shouldFindSingleClassWithPropertyPrefix() throws ClassNotFoundException, IOException {
-        final Class<?> clazz = factoryFinder.findClass("TestImplA", "prefix.");
+        final Class<?> clazz = factoryFinder.findClass("TestImplA", "prefix.").orElse(null);
 
         assertEquals(TestImplA.class, clazz);
     }
 
     @Test
     public void shouldFindSingleClassWithPropertyPrefixAndExpectedType() throws ClassNotFoundException, IOException {
-        final Class<?> clazz = factoryFinder.findClass("TestImplA", "prefix.", TestType.class);
+        final Class<?> clazz = factoryFinder.findClass("TestImplA", "prefix.", TestType.class).orElse(null);
 
         assertEquals(TestImplA.class, clazz);
     }