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

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k-runtime.git


The following commit(s) were added to refs/heads/master by this push:
     new 89d6bcf  Allow to use any class as configuration source
89d6bcf is described below

commit 89d6bcf95d4f0903aef04ada1f588ea5ef41b29a
Author: lburgazzoli <lburgazz...@gmail.com>
AuthorDate: Fri Nov 22 19:05:04 2019 +0100

    Allow to use any class as configuration source
---
 camel-k-loader-groovy/pom.xml                      |  11 ++
 ...utesLoader.groovy => GroovySourceLoader.groovy} |  15 ++-
 .../services/org/apache/camel/k/loader/groovy      |   2 +-
 .../apache/camel/k/loader/groovy/LoaderTest.groovy |  80 ++++++++----
 camel-k-loader-java/pom.xml                        |  11 ++
 ...urceRoutesLoader.java => JavaSourceLoader.java} |  24 ++--
 .../services/org/apache/camel/k/loader/java        |  18 ---
 .../camel/k/loader/java/RoutesLoaderTest.java      | 121 ++++++++++++-----
 .../src/test/resources/MyRoutesConfig.java         |  25 ++--
 camel-k-loader-js/pom.xml                          |  11 ++
 ...utesLoader.java => JavaScriptSourceLoader.java} |  15 ++-
 .../META-INF/services/org/apache/camel/k/loader/js |  18 ---
 .../apache/camel/k/loader/js/RoutesLoaderTest.java |  48 +++++--
 camel-k-loader-knative/pom.xml                     |  11 ++
 .../k/loader/knative/KnativeSourceLoader.java      | 143 +++++++++++++++++++++
 .../loader/knative/KnativeSourceRoutesLoader.java  | 101 ---------------
 .../org/apache/camel/k/loader/knative-source       |  18 ---
 .../apache/camel/k/loader/knative-source-groovy    |  18 ---
 .../org/apache/camel/k/loader/knative-source-java  |  18 ---
 .../org/apache/camel/k/loader/knative-source-js    |  18 ---
 .../org/apache/camel/k/loader/knative-source-kts   |  18 ---
 .../org/apache/camel/k/loader/knative-source-xml   |  18 ---
 .../org/apache/camel/k/loader/knative-source-yaml  |  18 ---
 .../knative/KnativeSourceRoutesLoaderTest.java     |  55 ++++++--
 camel-k-loader-kotlin/pom.xml                      |  36 +++++-
 ...KotlinRoutesLoader.kt => KotlinSourceLoader.kt} |  17 ++-
 .../services/org/apache/camel/k/loader/kts         |  18 ---
 .../org/apache/camel/k/loader/kotlin/LoaderTest.kt |  52 ++++++--
 camel-k-loader-xml/pom.xml                         |  11 ++
 .../{XmlRoutesLoader.java => XmlSourceLoader.java} |  16 ++-
 .../services/org/apache/camel/k/loader/xml         |  18 ---
 .../camel/k/loader/xml/RoutesLoaderTest.java       |  42 +++++-
 camel-k-loader-yaml/pom.xml                        |   1 -
 ...YamlRoutesLoader.java => YamlSourceLoader.java} |  13 +-
 .../camel/k/loader/yaml/RouteDefinitionTest.groovy |  12 +-
 .../apache/camel/k/loader/yaml/TestSupport.groovy  |   4 +-
 .../k/core/quarkus/RuntimeListenerAdapter.java     |  10 +-
 .../loader/js/quarkus/deployment/Application.java  |  11 +-
 .../loader/xml/quarkus/deployment/Application.java |  11 +-
 .../yaml/quarkus/deployment/Application.java       |  11 +-
 .../src/main/java/org/apache/camel/k/Runtime.java  |   4 +
 .../k/{RoutesLoader.java => SourceLoader.java}     |   7 +-
 .../apache/camel/k/listener/RoutesConfigurer.java  |  15 +--
 .../org/apache/camel/k/support/RuntimeSupport.java |  18 +--
 .../knative/yaml/parser/KnativeConverterTest.java  |  44 +++++--
 .../apache/camel/k/main/ApplicationRuntime.java    |   5 +
 .../java/org/apache/camel/k/main/RuntimeTest.java  |   5 +-
 .../src/test/resources/MyRoutesConfig.java         |  25 ++--
 .../java/org/apache/camel/k/annotation/Loader.java |   2 +-
 .../apache/camel/k/tooling/apt/CamelProcessor.java |  12 +-
 50 files changed, 719 insertions(+), 536 deletions(-)

diff --git a/camel-k-loader-groovy/pom.xml b/camel-k-loader-groovy/pom.xml
index 992ff9e..1c7a246 100644
--- a/camel-k-loader-groovy/pom.xml
+++ b/camel-k-loader-groovy/pom.xml
@@ -65,6 +65,17 @@
             <scope>provided</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-apt</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-annotations</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <!-- ******************************* -->
         <!-- test deps :: camel              -->
         <!-- ******************************* -->
diff --git 
a/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovyRoutesLoader.groovy
 
b/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovySourceLoader.groovy
similarity index 86%
rename from 
camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovyRoutesLoader.groovy
rename to 
camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovySourceLoader.groovy
index 6ed4f31..f721ceb 100644
--- 
a/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovyRoutesLoader.groovy
+++ 
b/camel-k-loader-groovy/src/main/groovy/org/apache/camel/k/loader/groovy/GroovySourceLoader.groovy
@@ -16,24 +16,23 @@
  */
 package org.apache.camel.k.loader.groovy
 
-import org.apache.camel.CamelContext
-import org.apache.camel.builder.RouteBuilder
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder
-import org.apache.camel.k.RoutesLoader
+import org.apache.camel.k.Runtime
 import org.apache.camel.k.Source
+import org.apache.camel.k.SourceLoader
 import org.apache.camel.k.loader.groovy.dsl.IntegrationConfiguration
 import org.codehaus.groovy.control.CompilerConfiguration
 import org.codehaus.groovy.control.customizers.ImportCustomizer
 
-class GroovyRoutesLoader implements RoutesLoader {
+class GroovySourceLoader implements SourceLoader {
     @Override
     List<String> getSupportedLanguages() {
-        return Collections.singletonList("groovy")
+        return Collections.singletonList('groovy')
     }
 
     @Override
-    RouteBuilder load(CamelContext camelContext, Source source) throws 
Exception {
-        return new EndpointRouteBuilder() {
+    void load(Runtime runtime, Source source) throws Exception {
+        def builder = new EndpointRouteBuilder() {
             @Override
             void configure() throws Exception {
                 def ic = new ImportCustomizer()
@@ -58,5 +57,7 @@ class GroovyRoutesLoader implements RoutesLoader {
                 }
             }
         }
+
+        runtime.addRoutes(builder)
     }
 }
diff --git 
a/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy
 
b/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy
index 006db95..4c39f93 100644
--- 
a/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy
+++ 
b/camel-k-loader-groovy/src/main/resources/META-INF/services/org/apache/camel/k/loader/groovy
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-class=org.apache.camel.k.loader.groovy.GroovyRoutesLoader
\ No newline at end of file
+class=org.apache.camel.k.loader.groovy.GroovySourceLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy
 
b/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy
index 48e5285..64b4010 100644
--- 
a/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy
+++ 
b/camel-k-loader-groovy/src/test/groovy/org/apache/camel/k/loader/groovy/LoaderTest.groovy
@@ -16,7 +16,11 @@
  */
 package org.apache.camel.k.loader.groovy
 
+import org.apache.camel.CamelContext
+import org.apache.camel.RoutesBuilder
+import org.apache.camel.builder.RouteBuilder
 import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.k.Runtime
 import org.apache.camel.k.Sources
 import org.apache.camel.k.support.RuntimeSupport
 import org.apache.camel.model.FromDefinition
@@ -27,52 +31,76 @@ class LoaderTest extends Specification {
 
     def "load routes"() {
         given:
-            def context = new DefaultCamelContext()
+            def runtime = new TestRuntime()
             def source = Sources.fromURI("classpath:routes.groovy")
 
         when:
-            def loader = RuntimeSupport.loaderFor(context, source)
-            def builder = loader.load(context, source)
+            def loader = RuntimeSupport.loaderFor(runtime.camelContext, source)
+            loader.load(runtime, source)
 
         then:
-            loader instanceof GroovyRoutesLoader
-            builder != null
+            loader instanceof GroovySourceLoader
+            runtime.builders.size() == 1
+            runtime.builders[0] instanceof RouteBuilder
 
-            builder.setContext(context)
-            builder.configure()
+            with(runtime.builders[0], RouteBuilder) {
+                it.setContext(runtime.camelContext)
+                it.configure()
 
-            def routes = builder.routeCollection.routes
+                def routes = it.routeCollection.routes
 
-            routes.size() == 1
-            routes[0].outputs[0] instanceof ToDefinition
-            routes[0].input.endpointUri == 'timer:tick'
+                routes.size() == 1
+                routes[0].outputs[0] instanceof ToDefinition
+                routes[0].input.endpointUri == 'timer:tick'
+            }
     }
 
     def "load routes with endpoint dsl"() {
         given:
-            def context = new DefaultCamelContext()
+            def runtime = new TestRuntime()
             def source = 
Sources.fromURI("classpath:routes-with-endpoint-dsl.groovy")
 
         when:
-            def loader = RuntimeSupport.loaderFor(context, source)
-            def builder = loader.load(context, source)
+            def loader = RuntimeSupport.loaderFor(runtime.camelContext, source)
+            loader.load(runtime, source)
 
         then:
-            loader instanceof GroovyRoutesLoader
-            builder != null
-
-            builder.setContext(context)
-            builder.configure()
+            loader instanceof GroovySourceLoader
+            runtime.builders.size() == 1
 
-            def routes = builder.routeCollection.routes
+            with(runtime.builders[0], RouteBuilder) {
+                it.setContext(runtime.camelContext)
+                it.configure()
 
-            routes.size() == 1
+                def routes = it.routeCollection.routes
+                routes.size() == 1
 
-            with(routes[0].input, FromDefinition) {
-                it.endpointUri == 'timer:tick?period=1s'
-            }
-            with(routes[0].outputs[0], ToDefinition) {
-                it.endpointUri == 'log:info'
+                with(routes[0].input, FromDefinition) {
+                    it.endpointUri == 'timer:tick?period=1s'
+                }
+                with(routes[0].outputs[0], ToDefinition) {
+                    it.endpointUri == 'log:info'
+                }
             }
     }
+
+    static class TestRuntime implements Runtime {
+        private final CamelContext camelContext
+        private final List<RoutesBuilder> builders
+
+        TestRuntime() {
+            this.camelContext = new DefaultCamelContext()
+            this.builders = new ArrayList<>()
+        }
+
+        @Override
+        CamelContext getCamelContext() {
+            return this.camelContext
+        }
+
+        @Override
+        void addRoutes(RoutesBuilder builder) {
+            this.builders.add(builder)
+        }
+    }
 }
diff --git a/camel-k-loader-java/pom.xml b/camel-k-loader-java/pom.xml
index bfc7e72..a49d0b5 100644
--- a/camel-k-loader-java/pom.xml
+++ b/camel-k-loader-java/pom.xml
@@ -49,6 +49,17 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-apt</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-annotations</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-main</artifactId>
             <scope>test</scope>
diff --git 
a/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceRoutesLoader.java
 
b/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceLoader.java
similarity index 74%
rename from 
camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceRoutesLoader.java
rename to 
camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceLoader.java
index 8208fdc..1a5b3f2 100644
--- 
a/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceRoutesLoader.java
+++ 
b/camel-k-loader-java/src/main/java/org/apache/camel/k/loader/java/JavaSourceLoader.java
@@ -23,33 +23,39 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
+import org.apache.camel.k.annotation.Loader;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.joor.Reflect;
 
-public class JavaSourceRoutesLoader implements RoutesLoader {
+@Loader("java")
+public class JavaSourceLoader implements SourceLoader {
     @Override
     public List<String> getSupportedLanguages() {
         return Collections.singletonList("java");
     }
 
     @Override
-    public RouteBuilder load(CamelContext camelContext, Source source) throws 
Exception {
-        try (InputStream is = source.resolveAsInputStream(camelContext)) {
+    public void load(Runtime runtime, Source source) throws Exception {
+        try (InputStream is = 
source.resolveAsInputStream(runtime.getCamelContext())) {
             final String content = IOUtils.toString(is, 
StandardCharsets.UTF_8);
             final String name = determineQualifiedName(source, content);
             final Reflect compiled = Reflect.compile(name, content);
+            final Object instance = compiled.create().get();
 
-            RouteBuilder rb =  compiled.create().get();
-            return rb;
+            if (instance instanceof RoutesBuilder) {
+                runtime.addRoutes((RoutesBuilder)instance);
+            } else {
+                runtime.addConfiguration(instance);
+            }
         }
     }
 
-    private static String determineQualifiedName(Source source, String 
content) throws Exception {
+    private static String determineQualifiedName(Source source, String 
content) {
         String name = source.getName();
         name = StringUtils.removeEnd(name, ".java");
 
diff --git 
a/camel-k-loader-java/src/main/resources/META-INF/services/org/apache/camel/k/loader/java
 
b/camel-k-loader-java/src/main/resources/META-INF/services/org/apache/camel/k/loader/java
deleted file mode 100644
index 2118cbc..0000000
--- 
a/camel-k-loader-java/src/main/resources/META-INF/services/org/apache/camel/k/loader/java
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.java.JavaSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java
 
b/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java
index 6d73eb5..f1c56c6 100644
--- 
a/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java
+++ 
b/camel-k-loader-java/src/test/java/org/apache/camel/k/loader/java/RoutesLoaderTest.java
@@ -16,17 +16,19 @@
  */
 package org.apache.camel.k.loader.java;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Stream;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
 import org.apache.camel.k.support.RuntimeSupport;
-import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ProcessDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.SetBodyDefinition;
@@ -41,16 +43,18 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class RoutesLoaderTest {
     @Test
     public void testLoadJavaWithNestedClass() throws Exception {
-        CamelContext context = new DefaultCamelContext();
-
+        TestRuntime runtime = new TestRuntime();
         Source source = 
Sources.fromURI("classpath:MyRoutesWithNestedClass.java");
-        RoutesLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(context, source);
+        SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, 
source);
+
+        loader.load(runtime, source);
 
-        assertThat(loader).isInstanceOf(JavaSourceRoutesLoader.class);
-        assertThat(builder).isNotNull();
+        assertThat(loader).isInstanceOf(JavaSourceLoader.class);
+        assertThat(runtime.builders).hasSize(1);
+        assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class);
 
-        builder.setContext(context);
+        RouteBuilder builder = (RouteBuilder)runtime.builders.get(0);
+        builder.setContext(runtime.getCamelContext());
         builder.configure();
 
         List<RouteDefinition> routes = 
builder.getRouteCollection().getRoutes();
@@ -63,35 +67,50 @@ public class RoutesLoaderTest {
 
     @Test
     public void testLoadJavaWithRestConfiguration() throws Exception {
-        CamelContext context = new DefaultCamelContext();
-
+        TestRuntime runtime = new TestRuntime();
         Source source = 
Sources.fromURI("classpath:MyRoutesWithRestConfiguration.java");
-        RoutesLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(context, source);
+        SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, 
source);
+
+        loader.load(runtime, source);
 
-        assertThat(loader).isInstanceOf(JavaSourceRoutesLoader.class);
-        assertThat(builder).isNotNull();
+        assertThat(loader).isInstanceOf(JavaSourceLoader.class);
+        assertThat(runtime.builders).hasSize(1);
+        assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class);
 
-        context.addRoutes(builder);
+        runtime.getCamelContext().addRoutes(runtime.builders.get(0));
 
-        assertThat(context.getRestConfigurations()).hasSize(1);
-        
assertThat(context.getRestConfigurations().iterator().next()).hasFieldOrPropertyWithValue("component",
 "restlet");
+        
assertThat(runtime.getCamelContext().getRestConfigurations()).hasSize(1);
+        
assertThat(runtime.getCamelContext().getRestConfigurations().iterator().next()).hasFieldOrPropertyWithValue("component",
 "restlet");
     }
 
     @Test
-    public void testLoadJavaWithModel() throws Exception {
-        CamelContext context = new DefaultCamelContext();
+    public void testLoadJavaConfiguration() throws Exception {
+        TestRuntime runtime = new TestRuntime();
+        Source source = Sources.fromURI("classpath:MyRoutesConfig.java");
+        SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, 
source);
+
+        loader.load(runtime, source);
+
+        assertThat(loader).isInstanceOf(JavaSourceLoader.class);
+        assertThat(runtime.builders).isEmpty();
+        assertThat(runtime.configurations).hasSize(1);
+    }
 
+    @Test
+    public void testLoadJavaWithModel() throws Exception {
+        TestRuntime runtime = new TestRuntime();
         Source source = Sources.fromURI("classpath:MyRoutesWithModel.java");
-        RoutesLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(context, source);
+        SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, 
source);
 
-        assertThat(loader).isInstanceOf(JavaSourceRoutesLoader.class);
-        assertThat(builder).isNotNull();
+        loader.load(runtime, source);
 
-        context.addRoutes(builder);
+        assertThat(loader).isInstanceOf(JavaSourceLoader.class);
+        assertThat(runtime.builders).hasSize(1);
+        assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class);
 
-        
assertThat(context.adapt(ModelCamelContext.class).getRestDefinitions()).first().satisfies(definition
 -> {
+        runtime.getCamelContext().addRoutes(runtime.builders.get(0));
+
+        
assertThat(runtime.camelContext.getRestDefinitions()).first().satisfies(definition
 -> {
             assertThat(definition.getVerbs()).first().satisfies(verb -> {
                 assertThat(verb).hasFieldOrPropertyWithValue("outType", 
"org.apache.camel.k.loader.java.model.EmployeeDTO");
             });
@@ -100,15 +119,19 @@ public class RoutesLoaderTest {
 
     @ParameterizedTest
     @MethodSource("parameters")
-    public void testLoaders(String location, Class<? extends RoutesLoader> 
type) throws Exception {
+    public void testLoaders(String location, Class<? extends SourceLoader> 
type) throws Exception {
+        TestRuntime runtime = new TestRuntime();
         Source source = Sources.fromURI(location);
-        RoutesLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new DefaultCamelContext(), source);
+        SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, 
source);
+
+        loader.load(runtime, source);
 
         assertThat(loader).isInstanceOf(type);
-        assertThat(builder).isNotNull();
+        assertThat(runtime.builders).hasSize(1);
+        assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class);
 
-        builder.setContext(new DefaultCamelContext());
+        RouteBuilder builder = (RouteBuilder)runtime.builders.get(0);
+        builder.setContext(runtime.getCamelContext());
         builder.configure();
 
         List<RouteDefinition> routes = 
builder.getRouteCollection().getRoutes();
@@ -119,10 +142,38 @@ public class RoutesLoaderTest {
 
     static Stream<Arguments> parameters() {
         return Stream.of(
-            Arguments.arguments("classpath:MyRoutes.java", 
JavaSourceRoutesLoader.class),
-            
Arguments.arguments("classpath:MyRoutesWithNameOverride.java?name=MyRoutes.java",
 JavaSourceRoutesLoader.class),
-            Arguments.arguments("classpath:MyRoutesWithPackage.java", 
JavaSourceRoutesLoader.class),
-            Arguments.arguments("classpath:MyRoutesWithEndpointDsl.java", 
JavaSourceRoutesLoader.class)
+            Arguments.arguments("classpath:MyRoutes.java", 
JavaSourceLoader.class),
+            
Arguments.arguments("classpath:MyRoutesWithNameOverride.java?name=MyRoutes.java",
 JavaSourceLoader.class),
+            Arguments.arguments("classpath:MyRoutesWithPackage.java", 
JavaSourceLoader.class),
+            Arguments.arguments("classpath:MyRoutesWithEndpointDsl.java", 
JavaSourceLoader.class)
         );
     }
+
+    static class TestRuntime implements Runtime {
+        private final DefaultCamelContext camelContext;
+        private final List<RoutesBuilder> builders;
+        private final List<Object> configurations;
+
+        public TestRuntime() {
+            this.camelContext = new DefaultCamelContext();
+            this.builders = new ArrayList<>();
+            this.configurations = new ArrayList<>();
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return this.camelContext;
+        }
+
+        @Override
+        public void addRoutes(RoutesBuilder builder) {
+            this.builders.add(builder);
+        }
+
+        @Override
+        public void addConfiguration(Object configuration) {
+            this.configurations.add(configuration);
+        }
+    }
 }
+
diff --git 
a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
 b/camel-k-loader-java/src/test/resources/MyRoutesConfig.java
similarity index 64%
copy from 
tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
copy to camel-k-loader-java/src/test/resources/MyRoutesConfig.java
index b94c3dc..bf733e7 100644
--- 
a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
+++ b/camel-k-loader-java/src/test/resources/MyRoutesConfig.java
@@ -14,15 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.k.annotation;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+public class MyRoutesConfig {
+    @BindToRegistry
+    public static MyProcessor myProcessor() {
+        return new MyProcessor();
+    }
 
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.SOURCE)
-public @interface Loader {
-    String value();
-}
+    public static class MyProcessor implements Processor {
+        @Override
+        public void process(Exchange exchange) throws Exception {
+        }
+    }
+}
\ No newline at end of file
diff --git a/camel-k-loader-js/pom.xml b/camel-k-loader-js/pom.xml
index ed8ad8c..fa3f9c1 100644
--- a/camel-k-loader-js/pom.xml
+++ b/camel-k-loader-js/pom.xml
@@ -48,6 +48,17 @@
             <version>${graalvm.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-apt</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-annotations</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <!-- ******************************* -->
         <!-- test deps :: camel              -->
         <!-- ******************************* -->
diff --git 
a/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptRoutesLoader.java
 
b/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptSourceLoader.java
similarity index 86%
rename from 
camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptRoutesLoader.java
rename to 
camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptSourceLoader.java
index 9ed6119..371b589 100644
--- 
a/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptRoutesLoader.java
+++ 
b/camel-k-loader-js/src/main/java/org/apache/camel/k/loader/js/JavaScriptSourceLoader.java
@@ -22,17 +22,20 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
+import org.apache.camel.k.annotation.Loader;
 import org.apache.camel.k.loader.js.dsl.IntegrationConfiguration;
 import org.apache.camel.support.LifecycleStrategySupport;
 import org.apache.commons.io.IOUtils;
 import org.graalvm.polyglot.Context;
 import org.graalvm.polyglot.Value;
 
-public class JavaScriptRoutesLoader implements RoutesLoader {
+@Loader("js")
+public class JavaScriptSourceLoader implements SourceLoader {
     private static final String LANGUAGE_ID = "js";
 
     @Override
@@ -41,8 +44,8 @@ public class JavaScriptRoutesLoader implements RoutesLoader {
     }
 
     @Override
-    public RouteBuilder load(CamelContext camelContext, Source source) throws 
Exception {
-        return new EndpointRouteBuilder() {
+    public void load(Runtime runtime, Source source) throws Exception {
+        RoutesBuilder builder = new EndpointRouteBuilder() {
             @Override
             public void configure() throws Exception {
                 final Context context = 
Context.newBuilder("js").allowAllAccess(true).build();
@@ -70,5 +73,7 @@ public class JavaScriptRoutesLoader implements RoutesLoader {
                 }
             }
         };
+
+        runtime.addRoutes(builder);
     }
 }
diff --git 
a/camel-k-loader-js/src/main/resources/META-INF/services/org/apache/camel/k/loader/js
 
b/camel-k-loader-js/src/main/resources/META-INF/services/org/apache/camel/k/loader/js
deleted file mode 100644
index dc6af3b..0000000
--- 
a/camel-k-loader-js/src/main/resources/META-INF/services/org/apache/camel/k/loader/js
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.js.JavaScriptRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java
 
b/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java
index 012b9ee..72e355d 100644
--- 
a/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java
+++ 
b/camel-k-loader-js/src/test/java/org/apache/camel/k/loader/js/RoutesLoaderTest.java
@@ -16,13 +16,17 @@
  */
 package org.apache.camel.k.loader.js;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Stream;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
 import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.model.RouteDefinition;
@@ -36,15 +40,19 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class RoutesLoaderTest {
     @ParameterizedTest
     @MethodSource("parameters")
-    public void testLoaders(String location, Class<? extends RoutesLoader> 
type) throws Exception {
+    public void testLoaders(String location, Class<? extends SourceLoader> 
type) throws Exception {
+        TestRuntime runtime = new TestRuntime();
         Source source = Sources.fromURI(location);
-        RoutesLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new DefaultCamelContext(), source);
+        SourceLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
+
+        loader.load(runtime, source);
 
         assertThat(loader).isInstanceOf(type);
-        assertThat(builder).isNotNull();
+        assertThat(runtime.builders).hasSize(1);
+        assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class);
 
-        builder.setContext(new DefaultCamelContext());
+        RouteBuilder builder = (RouteBuilder)runtime.builders.get(0);
+        builder.setContext(runtime.getCamelContext());
         builder.configure();
 
         List<RouteDefinition> routes = 
builder.getRouteCollection().getRoutes();
@@ -55,10 +63,30 @@ public class RoutesLoaderTest {
 
     static Stream<Arguments> parameters() {
         return Stream.of(
-            Arguments.arguments("classpath:routes.js", 
JavaScriptRoutesLoader.class),
-            Arguments.arguments("classpath:routes-with-endpoint-dsl.js", 
JavaScriptRoutesLoader.class),
-            
Arguments.arguments("classpath:routes-compressed.js.gz.b64?language=js&compression=true",
 JavaScriptRoutesLoader.class),
-            Arguments.arguments("classpath:routes.mytype?language=js", 
JavaScriptRoutesLoader.class)
+            Arguments.arguments("classpath:routes.js", 
JavaScriptSourceLoader.class),
+            Arguments.arguments("classpath:routes-with-endpoint-dsl.js", 
JavaScriptSourceLoader.class),
+            
Arguments.arguments("classpath:routes-compressed.js.gz.b64?language=js&compression=true",
 JavaScriptSourceLoader.class),
+            Arguments.arguments("classpath:routes.mytype?language=js", 
JavaScriptSourceLoader.class)
         );
     }
+
+    static class TestRuntime implements Runtime {
+        private final CamelContext camelContext;
+        private final List<RoutesBuilder> builders;
+
+        public TestRuntime() {
+            this.camelContext = new DefaultCamelContext();
+            this.builders = new ArrayList<>();
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return this.camelContext;
+        }
+
+        @Override
+        public void addRoutes(RoutesBuilder builder) {
+            this.builders.add(builder);
+        }
+    }
 }
diff --git a/camel-k-loader-knative/pom.xml b/camel-k-loader-knative/pom.xml
index 1f0cf4e..0a4d9ea 100644
--- a/camel-k-loader-knative/pom.xml
+++ b/camel-k-loader-knative/pom.xml
@@ -38,6 +38,17 @@
             <scope>provided</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-apt</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-annotations</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <!-- ****************************** -->
         <!--                                -->
         <!-- TESTS                          -->
diff --git 
a/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceLoader.java
 
b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceLoader.java
new file mode 100644
index 0000000..c5b11b8
--- /dev/null
+++ 
b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceLoader.java
@@ -0,0 +1,143 @@
+/*
+ * 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.k.loader.knative;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.k.Runtime;
+import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
+import org.apache.camel.k.annotation.Loader;
+import org.apache.camel.k.support.RuntimeSupport;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Loader({
+    "knative-source",
+    "knative-source-groovy",
+    "knative-source-java",
+    "knative-source-js",
+    "knative-source-kts",
+    "knative-source-xml",
+    "knative-source-yaml",
+})
+public class KnativeSourceLoader implements SourceLoader {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(KnativeSourceLoader.class);
+    private static final String LOADER_ID = "knative-source";
+    private static final String LANGUAGE_PREFIX = LOADER_ID + "-";
+
+    @Override
+    public List<String> getSupportedLanguages() {
+        return Arrays.asList(LANGUAGE_PREFIX + "yaml");
+    }
+
+    @Override
+    public void load(Runtime runtime, Source source) throws Exception {
+        if (LOADER_ID.equals(source.getLanguage())) {
+            throw new IllegalArgumentException("Cannot load source of type " + 
 source.getLanguage());
+        }
+
+        String languageId = source.getLanguage();
+        if (languageId.startsWith(LANGUAGE_PREFIX)) {
+            languageId = languageId.substring(LANGUAGE_PREFIX.length());
+        }
+
+        final CamelContext camelContext = runtime.getCamelContext();
+        final SourceLoader loader = 
RuntimeSupport.lookupLoaderByLanguage(camelContext, languageId);
+
+        loader.load(new RuntimeWrapper(runtime), source);
+    }
+
+    private static class RuntimeWrapper implements Runtime {
+        private final Runtime runtime;
+
+        RuntimeWrapper(Runtime runtime) {
+            this.runtime = runtime;
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return runtime.getCamelContext();
+        }
+
+        @Override
+        public void addRoutes(RoutesBuilder builder) {
+            if (builder instanceof RouteBuilder) {
+                runtime.addRoutes(new 
RouteBuilderWrapper((RouteBuilder)builder));
+            } else {
+                runtime.addRoutes(builder);
+            }
+        }
+    }
+
+    private static class RouteBuilderWrapper extends RouteBuilder {
+        private final RouteBuilder builder;
+
+        RouteBuilderWrapper(RouteBuilder builder) {
+            this.builder = builder;
+        }
+
+        @Override
+        public void setContext(CamelContext context) {
+            builder.setContext(context);
+        }
+
+        @Override
+        public void configure() throws Exception {
+        }
+
+        @Override
+        public void addRoutesToCamelContext(CamelContext context) throws 
Exception {
+            //TODO: this is a little hack as then configureRoutes will
+            //      be invoked twice: 1 by this hack and 1 by delegated
+            //      builder. Maybe, we should add builder lifecycle events.
+            List<RouteDefinition> definitions = 
builder.configureRoutes(context).getRoutes();
+
+            if (definitions.size() == 1) {
+                final String sink = 
context.resolvePropertyPlaceholders("{{env:KNATIVE_SINK:sink}}");
+                final String uri = String.format("knative://endpoint/%s", 
sink);
+                final RouteDefinition definition = definitions.get(0);
+
+                LOGGER.info("Add sink:{} to route:{}", uri, 
definition.getId());
+
+                // assuming that route is linear like there's no content based 
routing
+                // or ant other EIP that would branch the flow
+                definition.getOutputs().add(new ToDefinition(uri));
+            } else {
+                LOGGER.warn("Cannot determine route to enrich. the knative 
enpoint need to explicitly be defined");
+            }
+
+            //TODO: this is needed for java language because by default
+            //      camel main inspects route builders to detect beans
+            //      to be registered to the camel registry but as the
+            //      original builder is masked by this wrapping builder,
+            //      beans can't be automatically discovered
+            context.adapt(ExtendedCamelContext.class)
+                   .getBeanPostProcessor()
+                   .postProcessBeforeInitialization(builder, 
builder.getClass().getName());
+
+            builder.addRoutesToCamelContext(context);
+        }
+    }
+}
diff --git 
a/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java
 
b/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java
deleted file mode 100644
index be67dc9..0000000
--- 
a/camel-k-loader-knative/src/main/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoader.java
+++ /dev/null
@@ -1,101 +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.k.loader.knative;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.ExtendedCamelContext;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
-import org.apache.camel.k.Source;
-import org.apache.camel.k.support.RuntimeSupport;
-import org.apache.camel.model.RouteDefinition;
-import org.apache.camel.model.ToDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class KnativeSourceRoutesLoader implements RoutesLoader {
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(KnativeSourceRoutesLoader.class);
-    private static final String LOADER_ID = "knative-source";
-    private static final String LANGUAGE_PREFIX = LOADER_ID + "-";
-
-    @Override
-    public List<String> getSupportedLanguages() {
-        return Arrays.asList(LANGUAGE_PREFIX + "yaml");
-    }
-
-    @Override
-    public RouteBuilder load(CamelContext camelContext, Source source) throws 
Exception {
-        if (LOADER_ID.equals(source.getLanguage())) {
-            throw new IllegalArgumentException("Cannot load source of type " + 
 source.getLanguage());
-        }
-
-        String languageId = source.getLanguage();
-        if (languageId.startsWith(LANGUAGE_PREFIX)) {
-            languageId = languageId.substring(LANGUAGE_PREFIX.length());
-        }
-
-        final RoutesLoader loader = 
RuntimeSupport.lookupLoaderByLanguage(camelContext, languageId);
-        final RouteBuilder builder = loader.load(camelContext, source);
-
-        return new RouteBuilder() {
-            @Override
-            public void setContext(CamelContext context) {
-                builder.setContext(context);
-            }
-
-            @Override
-            public void configure() throws Exception {
-            }
-
-            @Override
-            public void addRoutesToCamelContext(CamelContext context) throws 
Exception {
-                //TODO: this is a little hack as then configureRoutes will
-                //      be invoked twice: 1 by this hack and 1 by delegated
-                //      builder. Maybe, we should add builder lifecycle events.
-                List<RouteDefinition> definitions = 
builder.configureRoutes(context).getRoutes();
-
-                if (definitions.size() == 1) {
-                    final String sink = 
context.resolvePropertyPlaceholders("{{env:KNATIVE_SINK:sink}}");
-                    final String uri = String.format("knative://endpoint/%s", 
sink);
-                    final RouteDefinition definition = definitions.get(0);
-
-                    LOGGER.info("Add sink:{} to route:{}", uri, 
definition.getId());
-
-                    // assuming that route is linear like there's no content 
based routing
-                    // or ant other EIP that would branch the flow
-                    definition.getOutputs().add(new ToDefinition(uri));
-                } else {
-                    LOGGER.warn("Cannot determine route to enrich. the knative 
enpoint need to explicitly be defined");
-                }
-
-                //TODO: this is needed for java language because by default
-                //      camel main inspects route builders to detect beans
-                //      to be registered to the camel registry but as the
-                //      original builder is masked by this wrapping builder,
-                //      beans can't be automatically discovered
-                context.adapt(ExtendedCamelContext.class)
-                    .getBeanPostProcessor()
-                    .postProcessBeforeInitialization(builder, 
builder.getClass().getName());
-
-                builder.addRoutesToCamelContext(context);
-            }
-        };
-    }
-}
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-groovy
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-java
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-js
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-kts
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-xml
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml
 
b/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml
deleted file mode 100644
index 6245d34..0000000
--- 
a/camel-k-loader-knative/src/main/resources/META-INF/services/org/apache/camel/k/loader/knative-source-yaml
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.knative.KnativeSourceRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java
 
b/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java
index bde067b..1e615fc 100644
--- 
a/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java
+++ 
b/camel-k-loader-knative/src/test/java/org/apache/camel/k/loader/knative/KnativeSourceRoutesLoaderTest.java
@@ -16,19 +16,22 @@
  */
 package org.apache.camel.k.loader.knative;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 import java.util.stream.Stream;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.knative.KnativeComponent;
 import org.apache.camel.component.knative.spi.Knative;
 import org.apache.camel.component.knative.spi.KnativeEnvironment;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
 import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.model.ModelCamelContext;
@@ -76,20 +79,23 @@ public class KnativeSourceRoutesLoaderTest {
             KnativeEnvironment.endpoint(Knative.EndpointKind.sink, "sink", 
"localhost", port)
         ));
 
-        CamelContext context = new DefaultCamelContext();
+        TestRuntime runtime = new TestRuntime();
+
+        CamelContext context = runtime.getCamelContext();
         context.disableJMX();
         context.setStreamCaching(true);
         context.addComponent("knative", component);
 
         Source source = Sources.fromURI(uri);
-        RoutesLoader loader = RuntimeSupport.loaderFor(context, source);
-        RouteBuilder builder = loader.load(context, source);
+        SourceLoader loader = RuntimeSupport.loaderFor(context, source);
+
+        loader.load(runtime, source);
 
-        assertThat(loader).isInstanceOf(KnativeSourceRoutesLoader.class);
-        assertThat(builder).isNotNull();
+        assertThat(loader).isInstanceOf(KnativeSourceLoader.class);
+        assertThat(runtime.builders).hasSize(1);
 
         try {
-            context.addRoutes(builder);
+            context.addRoutes(runtime.builders.get(0));
             context.addRoutes(new RouteBuilder() {
                 @Override
                 public void configure() throws Exception {
@@ -135,20 +141,23 @@ public class KnativeSourceRoutesLoaderTest {
             KnativeEnvironment.endpoint(Knative.EndpointKind.source, "sink", 
"localhost", port)
         ));
 
-        CamelContext context = new DefaultCamelContext();
+        TestRuntime runtime = new TestRuntime();
+
+        CamelContext context = runtime.getCamelContext();
         context.disableJMX();
         context.setStreamCaching(true);
         context.addComponent("knative", component);
 
         Source source = 
Sources.fromURI("classpath:routes.java?name=MyRoutes.java&loader=knative-source");
-        RoutesLoader loader = RuntimeSupport.loaderFor(context, source);
-        RouteBuilder builder = loader.load(context, source);
+        SourceLoader loader = RuntimeSupport.loaderFor(context, source);
 
-        assertThat(loader).isInstanceOf(KnativeSourceRoutesLoader.class);
-        assertThat(builder).isNotNull();
+        loader.load(runtime, source);
+
+        assertThat(loader).isInstanceOf(KnativeSourceLoader.class);
+        assertThat(runtime.builders).hasSize(1);
 
         try {
-            context.addRoutes(builder);
+            context.addRoutes(runtime.builders.get(0));
             context.start();
 
             
assertThat(context.getRegistry().lookupByName("my-bean")).isInstanceOfSatisfying(String.class,
 "my-bean-string"::equals);
@@ -156,4 +165,24 @@ public class KnativeSourceRoutesLoaderTest {
             context.stop();
         }
     }
+
+    static class TestRuntime implements Runtime {
+        private final CamelContext camelContext;
+        private final List<RoutesBuilder> builders;
+
+        public TestRuntime() {
+            this.camelContext = new DefaultCamelContext();
+            this.builders = new ArrayList<>();
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return this.camelContext;
+        }
+
+        @Override
+        public void addRoutes(RoutesBuilder builder) {
+            this.builders.add(builder);
+        }
+    }
 }
diff --git a/camel-k-loader-kotlin/pom.xml b/camel-k-loader-kotlin/pom.xml
index 028dbde..f518f49 100644
--- a/camel-k-loader-kotlin/pom.xml
+++ b/camel-k-loader-kotlin/pom.xml
@@ -73,6 +73,12 @@
             <version>${kotlin.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-annotations</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <!-- ******************************* -->
         <!-- test deps :: camel              -->
         <!-- ******************************* -->
@@ -156,8 +162,6 @@
     </dependencies>
 
     <build>
-        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
-        
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
         <plugins>
             <plugin>
                 <artifactId>kotlin-maven-plugin</artifactId>
@@ -168,16 +172,44 @@
                 </configuration>
                 <executions>
                     <execution>
+                        <id>kapt</id>
+                        <goals>
+                            <goal>kapt</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>src/main/kotlin</sourceDir>
+                            </sourceDirs>
+                            <annotationProcessorPaths>
+                                <annotationProcessorPath>
+                                    <groupId>org.apache.camel.k</groupId>
+                                    <artifactId>camel-k-apt</artifactId>
+                                    <version>${project.version}</version>
+                                </annotationProcessorPath>
+                            </annotationProcessorPaths>
+                        </configuration>
+                    </execution>
+                    <execution>
                         <id>compile</id>
                         <goals>
                             <goal>compile</goal>
                         </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>src/main/kotlin</sourceDir>
+                            </sourceDirs>
+                        </configuration>
                     </execution>
                     <execution>
                         <id>test-compile</id>
                         <goals>
                             <goal>test-compile</goal>
                         </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>src/test/kotlin</sourceDir>
+                            </sourceDirs>
+                        </configuration>
                     </execution>
                 </executions>
             </plugin>
diff --git 
a/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinRoutesLoader.kt
 
b/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinSourceLoader.kt
similarity index 87%
rename from 
camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinRoutesLoader.kt
rename to 
camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinSourceLoader.kt
index 90d3aa4..6fa8518 100644
--- 
a/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinRoutesLoader.kt
+++ 
b/camel-k-loader-kotlin/src/main/kotlin/org/apache/camel/k/loader/kotlin/KotlinSourceLoader.kt
@@ -16,10 +16,11 @@
  */
 package org.apache.camel.k.loader.kotlin
 
-import org.apache.camel.CamelContext
 import org.apache.camel.builder.endpoint.EndpointRouteBuilder
-import org.apache.camel.k.RoutesLoader
+import org.apache.camel.k.Runtime
 import org.apache.camel.k.Source
+import org.apache.camel.k.SourceLoader
+import org.apache.camel.k.annotation.Loader
 import org.apache.camel.k.loader.kotlin.dsl.IntegrationConfiguration
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
@@ -33,9 +34,10 @@ import 
kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
 import kotlin.script.experimental.jvmhost.JvmScriptCompiler
 import 
kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
 
-class KotlinRoutesLoader : RoutesLoader {
+@Loader("kts")
+class KotlinSourceLoader : SourceLoader {
     companion object {
-        val LOGGER : Logger = 
LoggerFactory.getLogger(KotlinRoutesLoader::class.java)
+        val LOGGER : Logger = 
LoggerFactory.getLogger(KotlinSourceLoader::class.java)
     }
 
     override fun getSupportedLanguages(): List<String> {
@@ -43,8 +45,8 @@ class KotlinRoutesLoader : RoutesLoader {
     }
 
     @Throws(Exception::class)
-    override fun load(camelContext: CamelContext, source: Source): 
EndpointRouteBuilder? {
-        return object : EndpointRouteBuilder() {
+    override fun load(runtime: Runtime, source: Source) {
+        var builder = object : EndpointRouteBuilder() {
             @Throws(Exception::class)
             override fun configure() {
                 val builder = this
@@ -52,6 +54,7 @@ class KotlinRoutesLoader : RoutesLoader {
                 val evaluator = BasicJvmScriptEvaluator()
                 val host = BasicJvmScriptingHost(compiler = compiler, 
evaluator = evaluator)
                 val config = 
createJvmCompilationConfigurationFromTemplate<IntegrationConfiguration>()
+                val camelContext = runtime.camelContext
 
                 source.resolveAsInputStream(camelContext).use { `is` ->
                     val result = host.eval(
@@ -75,5 +78,7 @@ class KotlinRoutesLoader : RoutesLoader {
                 }
             }
         }
+
+        runtime.addRoutes(builder)
     }
 }
diff --git 
a/camel-k-loader-kotlin/src/main/resources/META-INF/services/org/apache/camel/k/loader/kts
 
b/camel-k-loader-kotlin/src/main/resources/META-INF/services/org/apache/camel/k/loader/kts
deleted file mode 100644
index 48b587d..0000000
--- 
a/camel-k-loader-kotlin/src/main/resources/META-INF/services/org/apache/camel/k/loader/kts
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.kotlin.KotlinRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt
 
b/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt
index 00387ee..567a3d8 100644
--- 
a/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt
+++ 
b/camel-k-loader-kotlin/src/test/kotlin/org/apache/camel/k/loader/kotlin/LoaderTest.kt
@@ -16,27 +16,35 @@
  */
 package org.apache.camel.k.loader.kotlin
 
+import org.apache.camel.CamelContext
+import org.apache.camel.RoutesBuilder
+import org.apache.camel.builder.RouteBuilder
 import org.apache.camel.impl.DefaultCamelContext
+import org.apache.camel.k.Runtime
 import org.apache.camel.k.Sources
 import org.apache.camel.k.support.RuntimeSupport
 import org.apache.camel.model.ProcessDefinition
 import org.apache.camel.model.ToDefinition
 import org.assertj.core.api.Assertions.assertThat
 import org.junit.jupiter.api.Test
+import java.util.*
 
 class LoaderTest {
 
     @Test
     fun `load routes`() {
-        var context = DefaultCamelContext()
+        var runtime = TestRuntime()
         var source = Sources.fromURI("classpath:routes.kts")
-        val loader = RuntimeSupport.loaderFor(context, source)
-        val builder = loader.load(context, source)
+        val loader = RuntimeSupport.loaderFor(runtime.camelContext, source)
 
-        assertThat(loader).isInstanceOf(KotlinRoutesLoader::class.java)
-        assertThat(builder).isNotNull
+        loader.load(runtime, source)
 
-        builder.context = context
+        assertThat(loader).isInstanceOf(KotlinSourceLoader::class.java)
+        assertThat(runtime.builders).hasSize(1)
+        assertThat(runtime.builders[0]).isInstanceOf(RouteBuilder::class.java)
+
+        var builder = runtime.builders[0] as RouteBuilder
+        builder.context = runtime.camelContext
         builder.configure()
 
         val routes = builder.routeCollection.routes
@@ -48,15 +56,18 @@ class LoaderTest {
 
     @Test
     fun `load routes with endpoint dsl`() {
-        var context = DefaultCamelContext()
+        var runtime = TestRuntime()
         var source = Sources.fromURI("classpath:routes-with-endpoint-dsl.kts")
-        val loader = RuntimeSupport.loaderFor(context, source)
-        val builder = loader.load(context, source)
+        val loader = RuntimeSupport.loaderFor(runtime.camelContext, source)
+
+        loader.load(runtime, source)
 
-        assertThat(loader).isInstanceOf(KotlinRoutesLoader::class.java)
-        assertThat(builder).isNotNull
+        assertThat(loader).isInstanceOf(KotlinSourceLoader::class.java)
+        assertThat(runtime.builders).hasSize(1)
+        assertThat(runtime.builders[0]).isInstanceOf(RouteBuilder::class.java)
 
-        builder.context = context
+        var builder = runtime.builders[0] as RouteBuilder
+        builder.context = runtime.camelContext
         builder.configure()
 
         val routes = builder.routeCollection.routes
@@ -65,6 +76,23 @@ class LoaderTest {
         
assertThat(routes[0].outputs[0]).isInstanceOfSatisfying(ToDefinition::class.java)
 {
             assertThat(it.endpointUri).isEqualTo("log:info")
         }
+    }
 
+    internal class TestRuntime : Runtime {
+        private val context: CamelContext
+        val builders: MutableList<RoutesBuilder>
+
+        init {
+            this.context = DefaultCamelContext()
+            this.builders = ArrayList()
+        }
+
+        override fun getCamelContext(): CamelContext {
+            return this.context
+        }
+
+        override fun addRoutes(builder: RoutesBuilder) {
+            this.builders.add(builder)
+        }
     }
 }
diff --git a/camel-k-loader-xml/pom.xml b/camel-k-loader-xml/pom.xml
index 322f5fc..094d6cc 100644
--- a/camel-k-loader-xml/pom.xml
+++ b/camel-k-loader-xml/pom.xml
@@ -46,6 +46,17 @@
             <scope>provided</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-apt</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-annotations</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <!-- ****************************** -->
         <!--                                -->
         <!-- TESTS                          -->
diff --git 
a/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlRoutesLoader.java
 
b/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlSourceLoader.java
similarity index 88%
rename from 
camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlRoutesLoader.java
rename to 
camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlSourceLoader.java
index f981075..2da6fe6 100644
--- 
a/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlRoutesLoader.java
+++ 
b/camel-k-loader-xml/src/main/java/org/apache/camel/k/loader/xml/XmlSourceLoader.java
@@ -21,18 +21,20 @@ import java.util.Collections;
 import java.util.List;
 import javax.xml.bind.UnmarshalException;
 
-import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
+import org.apache.camel.k.annotation.Loader;
 import org.apache.camel.model.ModelHelper;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class XmlRoutesLoader implements RoutesLoader {
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(XmlRoutesLoader.class);
+@Loader("xml")
+public class XmlSourceLoader implements SourceLoader {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(XmlSourceLoader.class);
 
     @Override
     public List<String> getSupportedLanguages() {
@@ -40,8 +42,8 @@ public class XmlRoutesLoader implements RoutesLoader {
     }
 
     @Override
-    public RouteBuilder load(CamelContext camelContext, Source source) throws 
Exception {
-        return new RouteBuilder() {
+    public void load(Runtime runtime, Source source) throws Exception {
+        RouteBuilder builder = new RouteBuilder() {
             @Override
             public void configure() throws Exception {
                 try (InputStream is = 
source.resolveAsInputStream(getContext())) {
@@ -71,5 +73,7 @@ public class XmlRoutesLoader implements RoutesLoader {
                 }
             }
         };
+
+        runtime.addRoutes(builder);
     }
 }
diff --git 
a/camel-k-loader-xml/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml
 
b/camel-k-loader-xml/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml
deleted file mode 100644
index 5670bf1..0000000
--- 
a/camel-k-loader-xml/src/main/resources/META-INF/services/org/apache/camel/k/loader/xml
+++ /dev/null
@@ -1,18 +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.
-#
-
-class=org.apache.camel.k.loader.xml.XmlRoutesLoader
\ No newline at end of file
diff --git 
a/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java
 
b/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java
index 541a8b2..5af5d96 100644
--- 
a/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java
+++ 
b/camel-k-loader-xml/src/test/java/org/apache/camel/k/loader/xml/RoutesLoaderTest.java
@@ -16,13 +16,17 @@
  */
 package org.apache.camel.k.loader.xml;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Stream;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
 import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.model.RouteDefinition;
@@ -36,15 +40,19 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class RoutesLoaderTest {
     @ParameterizedTest
     @MethodSource("parameters")
-    public void testLoaders(String location, Class<? extends RoutesLoader> 
type) throws Exception {
+    public void testLoaders(String location, Class<? extends SourceLoader> 
type) throws Exception {
+        TestRuntime runtime = new TestRuntime();
         Source source = Sources.fromURI(location);
-        RoutesLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
-        RouteBuilder builder = loader.load(new DefaultCamelContext(), source);
+        SourceLoader loader = RuntimeSupport.loaderFor(new 
DefaultCamelContext(), source);
+
+        loader.load(runtime, source);
 
         assertThat(loader).isInstanceOf(type);
-        assertThat(builder).isNotNull();
+        assertThat(runtime.builders).hasSize(1);
+        assertThat(runtime.builders).first().isInstanceOf(RouteBuilder.class);
 
-        builder.setContext(new DefaultCamelContext());
+        RouteBuilder builder = (RouteBuilder)runtime.builders.get(0);
+        builder.setContext(runtime.getCamelContext());
         builder.configure();
 
         List<RouteDefinition> routes = 
builder.getRouteCollection().getRoutes();
@@ -55,7 +63,27 @@ public class RoutesLoaderTest {
 
     static Stream<Arguments> parameters() {
         return Stream.of(
-            Arguments.arguments("classpath:routes.xml", XmlRoutesLoader.class)
+            Arguments.arguments("classpath:routes.xml", XmlSourceLoader.class)
         );
     }
+
+    static class TestRuntime implements Runtime {
+        private final CamelContext camelContext;
+        private final List<RoutesBuilder> builders;
+
+        public TestRuntime() {
+            this.camelContext = new DefaultCamelContext();
+            this.builders = new ArrayList<>();
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return this.camelContext;
+        }
+
+        @Override
+        public void addRoutes(RoutesBuilder builder) {
+            this.builders.add(builder);
+        }
+    }
 }
diff --git a/camel-k-loader-yaml/pom.xml b/camel-k-loader-yaml/pom.xml
index 11631a8..9a6016d 100644
--- a/camel-k-loader-yaml/pom.xml
+++ b/camel-k-loader-yaml/pom.xml
@@ -60,7 +60,6 @@
             <artifactId>camel-k-apt</artifactId>
             <optional>true</optional>
         </dependency>
-
         <dependency>
             <groupId>org.apache.camel.k</groupId>
             <artifactId>camel-k-annotations</artifactId>
diff --git 
a/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlRoutesLoader.java
 
b/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlSourceLoader.java
similarity index 93%
rename from 
camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlRoutesLoader.java
rename to 
camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlSourceLoader.java
index 45d5801..5b15828 100644
--- 
a/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlRoutesLoader.java
+++ 
b/camel-k-loader-yaml/src/main/java/org/apache/camel/k/loader/yaml/YamlSourceLoader.java
@@ -31,8 +31,9 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
 import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
 import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.annotation.Loader;
 import org.apache.camel.k.loader.yaml.model.Step;
 import org.apache.camel.k.loader.yaml.parser.StartStepParser;
@@ -46,10 +47,10 @@ import org.apache.camel.model.rest.RestsDefinition;
 
 
 @Loader("yaml")
-public class YamlRoutesLoader implements RoutesLoader {
+public class YamlSourceLoader implements SourceLoader {
     private final ObjectMapper mapper;
 
-    public YamlRoutesLoader() {
+    public YamlSourceLoader() {
         YAMLFactory yamlFactory = new YAMLFactory()
             .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, true)
             .configure(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID, false);
@@ -71,8 +72,10 @@ public class YamlRoutesLoader implements RoutesLoader {
     }
 
     @Override
-    public RouteBuilder load(CamelContext camelContext, Source source) throws 
Exception {
-        return builder(source.resolveAsInputStream(camelContext));
+    public void load(Runtime runtime, Source source) throws Exception {
+        runtime.addRoutes(
+            builder(source.resolveAsInputStream(runtime.getCamelContext()))
+        );
     }
 
     final ObjectMapper mapper() {
diff --git 
a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy
 
b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy
index 534992a..b63d4ba 100644
--- 
a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy
+++ 
b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/RouteDefinitionTest.groovy
@@ -45,7 +45,7 @@ class RouteDefinitionTest extends TestSupport {
             def camelContext = new DefaultCamelContext()
             def istream = IOUtils.toInputStream(content, 
StandardCharsets.UTF_8)
         when:
-            camelContext.addRoutes(new YamlRoutesLoader().builder(istream))
+            camelContext.addRoutes(new YamlSourceLoader().builder(istream))
         then:
             camelContext.routeDefinitions[0].id == 'my-route-id'
             camelContext.routeDefinitions[0].group == 'my-route-group'
@@ -84,7 +84,7 @@ class RouteDefinitionTest extends TestSupport {
             def camelContext = new DefaultCamelContext()
             def istream = IOUtils.toInputStream(content, 
StandardCharsets.UTF_8)
         when:
-            camelContext.addRoutes(new YamlRoutesLoader().builder(istream))
+            camelContext.addRoutes(new YamlSourceLoader().builder(istream))
         then:
             camelContext.routeDefinitions[0].input.endpointUri == 
'direct:start'
 
@@ -130,7 +130,7 @@ class RouteDefinitionTest extends TestSupport {
             def camelContext = new DefaultCamelContext()
             def istream = IOUtils.toInputStream(content, 
StandardCharsets.UTF_8)
         when:
-            camelContext.addRoutes(new YamlRoutesLoader().builder(istream))
+            camelContext.addRoutes(new YamlSourceLoader().builder(istream))
         then:
             camelContext.routeDefinitions[0].input.endpointUri == 
'direct:start'
             camelContext.routeDefinitions[0].outputs.size() == 2
@@ -169,7 +169,7 @@ class RouteDefinitionTest extends TestSupport {
             def camelContext = new DefaultCamelContext()
             def istream = IOUtils.toInputStream(content, 
StandardCharsets.UTF_8)
         when:
-            camelContext.addRoutes(new YamlRoutesLoader().builder(istream))
+            camelContext.addRoutes(new YamlSourceLoader().builder(istream))
         then:
             camelContext.routeDefinitions[0].input.endpointUri == 
'direct:start'
             camelContext.routeDefinitions[0].outputs.size() == 1
@@ -204,7 +204,7 @@ class RouteDefinitionTest extends TestSupport {
             def camelContext = new DefaultCamelContext()
             def istream = IOUtils.toInputStream(content, 
StandardCharsets.UTF_8)
         when:
-            camelContext.addRoutes(new YamlRoutesLoader().builder(istream))
+            camelContext.addRoutes(new YamlSourceLoader().builder(istream))
         then:
             camelContext.routeDefinitions[0].input.endpointUri == 
'direct:start'
             camelContext.routeDefinitions[0].outputs.size() == 2
@@ -243,7 +243,7 @@ class RouteDefinitionTest extends TestSupport {
             def camelContext = new DefaultCamelContext()
             def istream = IOUtils.toInputStream(content, 
StandardCharsets.UTF_8)
         when:
-            camelContext.addRoutes(new YamlRoutesLoader().builder(istream))
+            camelContext.addRoutes(new YamlSourceLoader().builder(istream))
         then:
             camelContext.routeDefinitions[0].input.endpointUri == 
'direct:start'
             camelContext.routeDefinitions[0].outputs.size() == 1
diff --git 
a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy
 
b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy
index 776c550..400c59f 100644
--- 
a/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy
+++ 
b/camel-k-loader-yaml/src/test/groovy/org/apache/camel/k/loader/yaml/TestSupport.groovy
@@ -29,7 +29,7 @@ import java.nio.charset.StandardCharsets
 
 @Slf4j
 class TestSupport extends Specification {
-    static def MAPPER = new YamlRoutesLoader().mapper()
+    static def MAPPER = new YamlSourceLoader().mapper()
 
     static StepParser.Context stepContext(String content) {
         def node = MAPPER.readTree(content.stripMargin())
@@ -45,7 +45,7 @@ class TestSupport extends Specification {
     static CamelContext startContext(String content) {
         def context = new DefaultCamelContext()
         def istream = IOUtils.toInputStream(content.stripMargin(), 
StandardCharsets.UTF_8)
-        def builder = new YamlRoutesLoader().builder(istream)
+        def builder = new YamlSourceLoader().builder(istream)
 
         context.disableJMX()
         context.setStreamCaching(true)
diff --git 
a/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java
 
b/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java
index 2ca4f09..cd94032 100644
--- 
a/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java
+++ 
b/camel-k-quarkus/camel-k-quarkus-core/runtime/src/main/java/org/apache/camel/k/core/quarkus/RuntimeListenerAdapter.java
@@ -17,7 +17,6 @@
 package org.apache.camel.k.core.quarkus;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
@@ -43,10 +42,6 @@ public class RuntimeListenerAdapter implements MainListener {
         this.listeners.addAll(listeners);
     }
 
-    public List<Runtime.Listener> getListeners() {
-        return Collections.unmodifiableList(listeners);
-    }
-
     @Override
     public void beforeStart(BaseMainSupport main) {
         invokeListeners(listeners, on(main), Runtime.Phase.Starting);
@@ -104,6 +99,11 @@ public class RuntimeListenerAdapter implements MainListener 
{
             public void addRoutes(RoutesBuilder builder) {
                 main.addRoutesBuilder(builder);
             }
+
+            @Override
+            public void addConfiguration(Object configuration) {
+                main.addConfiguration(configuration);
+            }
         };
     }
 }
diff --git 
a/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java
 
b/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java
index 076bb89..88150d5 100644
--- 
a/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java
+++ 
b/camel-k-quarkus/camel-k-quarkus-loader-js/it/src/main/java/org/apache/camel/k/loader/js/quarkus/deployment/Application.java
@@ -30,11 +30,11 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Consume;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
-import org.apache.camel.k.loader.js.JavaScriptRoutesLoader;
+import org.apache.camel.k.loader.js.JavaScriptSourceLoader;
 
 @Path("/test")
 @ApplicationScoped
@@ -48,10 +48,9 @@ public class Application {
     @Produces(MediaType.APPLICATION_JSON)
     public JsonObject loadRoutes(@PathParam("name") String name, String code) 
throws Exception {
         final Source source = Sources.fromBytes(name, "js", null, 
code.getBytes(StandardCharsets.UTF_8));
-        final RoutesLoader loader = new JavaScriptRoutesLoader();
-        final RouteBuilder routes = loader.load(context, source);
+        final SourceLoader loader = new JavaScriptSourceLoader();
 
-        context.addRoutes(routes);
+        loader.load(Runtime.on(context), source);
 
         return Json.createObjectBuilder()
             .add("components", extractComponents())
diff --git 
a/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java
 
b/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java
index 4a89fbd..b5d9bfa 100644
--- 
a/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java
+++ 
b/camel-k-quarkus/camel-k-quarkus-loader-xml/it/src/main/java/org/apache/camel/k/loader/xml/quarkus/deployment/Application.java
@@ -30,11 +30,11 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Consume;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
-import org.apache.camel.k.loader.xml.XmlRoutesLoader;
+import org.apache.camel.k.loader.xml.XmlSourceLoader;
 
 @Path("/test")
 @ApplicationScoped
@@ -48,10 +48,9 @@ public class Application {
     @Produces(MediaType.APPLICATION_JSON)
     public JsonObject loadRoutes(@PathParam("name") String name, String code) 
throws Exception {
         final Source source = Sources.fromBytes(name, "xml", null, 
code.getBytes(StandardCharsets.UTF_8));
-        final RoutesLoader loader = new XmlRoutesLoader();
-        final RouteBuilder routes = loader.load(context, source);
+        final SourceLoader loader = new XmlSourceLoader();
 
-        context.addRoutes(routes);
+        loader.load(Runtime.on(context), source);
 
         return Json.createObjectBuilder()
             .add("components", extractComponents())
diff --git 
a/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java
 
b/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java
index c2eab1e..93d0d44 100644
--- 
a/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java
+++ 
b/camel-k-quarkus/camel-k-quarkus-loader-yaml/it/src/main/java/org/apache/camel/k/loader/yaml/quarkus/deployment/Application.java
@@ -30,11 +30,11 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Consume;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
-import org.apache.camel.k.loader.yaml.YamlRoutesLoader;
+import org.apache.camel.k.loader.yaml.YamlSourceLoader;
 
 @Path("/test")
 @ApplicationScoped
@@ -48,10 +48,9 @@ public class Application {
     @Produces(MediaType.APPLICATION_JSON)
     public JsonObject loadRoutes(@PathParam("name") String name, String code) 
throws Exception {
         final Source source = Sources.fromBytes(name, "yaml", null, 
code.getBytes(StandardCharsets.UTF_8));
-        final RoutesLoader loader = new YamlRoutesLoader();
-        final RouteBuilder routes = loader.load(context, source);
+        final SourceLoader loader = new YamlSourceLoader();
 
-        context.addRoutes(routes);
+        loader.load(Runtime.on(context), source);
 
         return Json.createObjectBuilder()
             .add("components", extractComponents())
diff --git a/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java 
b/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java
index a7990fe..e75d389 100644
--- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java
+++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/Runtime.java
@@ -53,6 +53,10 @@ public interface Runtime extends HasCamelContext {
         }
     }
 
+    default void addConfiguration(Object configuration) {
+        throw new UnsupportedOperationException();
+    }
+
     enum Phase {
         Starting,
         ConfigureContext,
diff --git 
a/camel-k-runtime-core/src/main/java/org/apache/camel/k/RoutesLoader.java 
b/camel-k-runtime-core/src/main/java/org/apache/camel/k/SourceLoader.java
similarity index 87%
rename from 
camel-k-runtime-core/src/main/java/org/apache/camel/k/RoutesLoader.java
rename to 
camel-k-runtime-core/src/main/java/org/apache/camel/k/SourceLoader.java
index c2a75f6..470a930 100644
--- a/camel-k-runtime-core/src/main/java/org/apache/camel/k/RoutesLoader.java
+++ b/camel-k-runtime-core/src/main/java/org/apache/camel/k/SourceLoader.java
@@ -18,10 +18,9 @@ package org.apache.camel.k;
 
 import java.util.List;
 
-import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 
-public interface RoutesLoader {
+public interface SourceLoader {
     /**
      * Provides a list of the languages supported by this loader.
      *
@@ -32,10 +31,10 @@ public interface RoutesLoader {
     /**
      * Creates a camel {@link RouteBuilder} from the given resource.
      *
-     * @param context the camel runtime.
+     * @param runtime the runtime.
      * @param source the source to load.
      * @return the RouteBuilder.
      * @throws Exception
      */
-    RouteBuilder load(CamelContext context, Source source) throws Exception;
+    void load(Runtime runtime, Source source) throws Exception;
 }
diff --git 
a/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java
 
b/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java
index 53ed7e0..4896705 100644
--- 
a/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java
+++ 
b/camel-k-runtime-core/src/main/java/org/apache/camel/k/listener/RoutesConfigurer.java
@@ -17,11 +17,10 @@
 package org.apache.camel.k.listener;
 
 import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.k.Constants;
-import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
 import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.util.ObjectHelper;
@@ -58,24 +57,18 @@ public class RoutesConfigurer extends AbstractPhaseListener 
{
             }
 
             final Source source;
-            final RoutesLoader loader;
-            final RouteBuilder builder;
+            final SourceLoader loader;
 
             try {
                 source = Sources.fromURI(route);
                 loader = RuntimeSupport.loaderFor(runtime.getCamelContext(), 
source);
-                builder = loader.load(runtime.getCamelContext(), source);
+
+                loader.load(runtime, source);
             } catch (Exception e) {
                 throw RuntimeCamelException.wrapRuntimeCamelException(e);
             }
 
-            if (builder == null) {
-                throw new IllegalStateException("Unable to load route from: " 
+ route);
-            }
-
             LOGGER.info("Loading routes from: {}", route);
-
-            runtime.addRoutes(builder);
         }
     }
 
diff --git 
a/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
 
b/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
index 52012ce..107b484 100644
--- 
a/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
+++ 
b/camel-k-runtime-core/src/main/java/org/apache/camel/k/support/RuntimeSupport.java
@@ -31,8 +31,8 @@ import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.k.Constants;
 import org.apache.camel.k.ContextCustomizer;
-import org.apache.camel.k.RoutesLoader;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -153,7 +153,7 @@ public final class RuntimeSupport {
     //
     // *********************************
 
-    public static RoutesLoader loaderFor(CamelContext context, Source source) {
+    public static SourceLoader loaderFor(CamelContext context, Source source) {
         return source.getLoader().map(
             loaderId -> lookupLoaderById(context, loaderId)
         ).orElseGet(
@@ -162,10 +162,10 @@ public final class RuntimeSupport {
     }
 
 
-    public static RoutesLoader lookupLoaderById(CamelContext context, String 
loaderId) {
+    public static SourceLoader lookupLoaderById(CamelContext context, String 
loaderId) {
         LOGGER.info("Looking up loader for id: {}", loaderId);
 
-        RoutesLoader loader = 
context.getRegistry().findByTypeWithName(RoutesLoader.class).get(loaderId);
+        SourceLoader loader = 
context.getRegistry().findByTypeWithName(SourceLoader.class).get(loaderId);
         if (loader != null) {
             LOGGER.info("Found loader {} with id {} from the registry", 
loader, loaderId);
             return loader;
@@ -174,10 +174,10 @@ public final class RuntimeSupport {
         return lookupLoaderFromResource(context, loaderId);
     }
 
-    public static RoutesLoader lookupLoaderByLanguage(CamelContext context, 
String loaderId) {
+    public static SourceLoader lookupLoaderByLanguage(CamelContext context, 
String loaderId) {
         LOGGER.info("Looking up loader for language: {}", loaderId);
 
-        for (RoutesLoader loader: 
context.getRegistry().findByType(RoutesLoader.class)) {
+        for (SourceLoader loader: 
context.getRegistry().findByType(SourceLoader.class)) {
             if (loader.getSupportedLanguages().contains(loaderId)) {
                 LOGGER.info("Found loader {} for language {} from the 
registry", loader, loaderId);
                 return loader;
@@ -187,13 +187,13 @@ public final class RuntimeSupport {
         return lookupLoaderFromResource(context, loaderId);
     }
 
-    public static RoutesLoader lookupLoaderFromResource(CamelContext context, 
String loaderId) {
-        RoutesLoader loader;
+    public static SourceLoader lookupLoaderFromResource(CamelContext context, 
String loaderId) {
+        SourceLoader loader;
 
         try {
             loader = context.adapt(ExtendedCamelContext.class)
                 .getFactoryFinder(Constants.ROUTES_LOADER_RESOURCE_PATH)
-                .newInstance(loaderId, RoutesLoader.class)
+                .newInstance(loaderId, SourceLoader.class)
                 .orElseThrow(() -> new RuntimeException("Error creating 
instance of loader: " + loaderId));
 
             LOGGER.info("Found loader {} for language {} from service 
definition", loader, loaderId);
diff --git 
a/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java
 
b/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java
index 15a1525..628fada 100644
--- 
a/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java
+++ 
b/camel-k-runtime-knative/src/test/java/org/apache/camel/k/knative/yaml/parser/KnativeConverterTest.java
@@ -16,14 +16,17 @@
  */
 package org.apache.camel.k.knative.yaml.parser;
 
+import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.k.RoutesLoader;
+import org.apache.camel.k.Runtime;
 import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
 import org.apache.camel.k.Sources;
-import org.apache.camel.k.loader.yaml.YamlRoutesLoader;
+import org.apache.camel.k.loader.yaml.YamlSourceLoader;
 import org.apache.camel.k.support.RuntimeSupport;
 import org.apache.camel.model.FromDefinition;
 import org.apache.camel.model.ProcessorDefinition;
@@ -37,17 +40,18 @@ public class KnativeConverterTest {
 
     @Test
     public void testLoadRoutes() throws Exception {
-        DefaultCamelContext context = new DefaultCamelContext();
+        TestRuntime runtime = new TestRuntime();
         Source source = Sources.fromURI("classpath:route.yaml");
-        RoutesLoader loader = RuntimeSupport.loaderFor(context, source);
-        RouteBuilder builder = loader.load(context, source);
+        SourceLoader loader = RuntimeSupport.loaderFor(runtime.camelContext, 
source);
 
-        assertThat(loader).isInstanceOf(YamlRoutesLoader.class);
-        assertThat(builder).isNotNull();
+        loader.load(runtime, source);
 
-        context.addRoutes(builder);
+        assertThat(loader).isInstanceOf(YamlSourceLoader.class);
+        assertThat(runtime.builders).hasSize(1);
 
-        List<RouteDefinition> routes = context.getRouteDefinitions();
+        runtime.camelContext.addRoutes(runtime.builders.get(0));
+
+        List<RouteDefinition> routes = 
runtime.camelContext.getRouteDefinitions();
         assertThat(routes).hasSize(1);
 
         // definition
@@ -90,4 +94,24 @@ public class KnativeConverterTest {
                 
assertThat(t.getEndpointUri()).isEqualTo("knative:endpoint/to");
             });
     }
+
+    static class TestRuntime implements Runtime {
+        private final DefaultCamelContext camelContext;
+        private final List<RoutesBuilder> builders;
+
+        public TestRuntime() {
+            this.camelContext = new DefaultCamelContext();
+            this.builders = new ArrayList<>();
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return this.camelContext;
+        }
+
+        @Override
+        public void addRoutes(RoutesBuilder builder) {
+            this.builders.add(builder);
+        }
+    }
 }
diff --git 
a/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
 
b/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
index b91f7d5..470d0c5 100644
--- 
a/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
+++ 
b/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
@@ -80,6 +80,11 @@ public final class ApplicationRuntime implements Runtime {
     }
 
     @Override
+    public void addConfiguration(Object configuration) {
+        this.main.addConfiguration(configuration);
+    }
+
+    @Override
     public void setProperties(Properties properties) {
         this.main.setOverrideProperties(properties);
     }
diff --git 
a/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java 
b/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java
index ffa89e2..b5256e5 100644
--- 
a/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java
+++ 
b/camel-k-runtime-main/src/test/java/org/apache/camel/k/main/RuntimeTest.java
@@ -93,12 +93,13 @@ public class RuntimeTest {
     }
 
     @Test
-    public void testLoadJavaSourceWithBeans() throws Exception {
+    public void testLoadJavaSource() throws Exception {
         ApplicationRuntime runtime = new ApplicationRuntime();
-        
runtime.addListener(RoutesConfigurer.forRoutes("classpath:MyRoutesWithBeans.java"));
+        
runtime.addListener(RoutesConfigurer.forRoutes("classpath:MyRoutesWithBeans.java",
 "classpath:MyRoutesConfig.java"));
         runtime.addListener(Runtime.Phase.Started, r ->  runtime.stop());
         runtime.run();
 
+        
assertThat(runtime.getRegistry().lookupByName("my-processor")).isNotNull();
         
assertThat(runtime.getRegistry().lookupByName("my-bean")).isInstanceOfSatisfying(MyBean.class,
 b -> {
             assertThat(b).hasFieldOrPropertyWithValue("name", "my-bean-name");
         });
diff --git 
a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
 b/camel-k-runtime-main/src/test/resources/MyRoutesConfig.java
similarity index 63%
copy from 
tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
copy to camel-k-runtime-main/src/test/resources/MyRoutesConfig.java
index b94c3dc..65f8a05 100644
--- 
a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
+++ b/camel-k-runtime-main/src/test/resources/MyRoutesConfig.java
@@ -14,15 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.k.annotation;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+public class MyRoutesConfig {
+    @BindToRegistry("my-processor")
+    public static MyProcessor myProcessor() {
+        return new MyProcessor();
+    }
 
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.SOURCE)
-public @interface Loader {
-    String value();
-}
+    public static class MyProcessor implements Processor {
+        @Override
+        public void process(Exchange exchange) throws Exception {
+        }
+    }
+}
\ No newline at end of file
diff --git 
a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
 
b/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
index b94c3dc..89ea1e6 100644
--- 
a/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
+++ 
b/tooling/camel-k-annotations/src/main/java/org/apache/camel/k/annotation/Loader.java
@@ -24,5 +24,5 @@ import java.lang.annotation.Target;
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.SOURCE)
 public @interface Loader {
-    String value();
+    String[] value();
 }
diff --git 
a/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java
 
b/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java
index cb40d65..269bf45 100644
--- 
a/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java
+++ 
b/tooling/camel-k-apt/src/main/java/org/apache/camel/k/tooling/apt/CamelProcessor.java
@@ -53,10 +53,14 @@ public class CamelProcessor extends AbstractProcessor {
         for (TypeElement annotation : annotations) {
             Set<? extends Element> ae = 
roundEnv.getElementsAnnotatedWith(annotation);
             for (Element element: ae) {
-                on(element, Loader.class, (e, a) -> service(
-                    output("META-INF/services/org/apache/camel/k/loader/%s", 
a.value()),
-                    e
-                ));
+                on(element, Loader.class, (e, a) -> {
+                    for (String loader: a.value()) {
+                        service(
+                            
output("META-INF/services/org/apache/camel/k/loader/%s", loader),
+                            e
+                        );
+                    }
+                });
                 on(element, YAMLStepParser.class, (e, a) -> {
                     for (String id: a.value()) {
                         service(

Reply via email to