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

fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 675f09eddf0 CAMEL-22423: Start the ContextServiceLoaderPluginResolver
675f09eddf0 is described below

commit 675f09eddf0a0e2390e4477195cdfc9c423c4d25
Author: Croway <[email protected]>
AuthorDate: Thu Sep 18 14:57:51 2025 +0200

    CAMEL-22423: Start the ContextServiceLoaderPluginResolver
---
 .../spi/ContextServiceLoaderPluginResolver.java    | 41 ++++++++++++++++++++++
 .../camel/impl/engine/AbstractCamelContext.java    | 23 ++++++++++--
 .../engine/DefaultContextServiceLoaderPlugin.java  |  6 ++--
 .../camel/impl/engine/SimpleCamelContext.java      |  4 +--
 .../java/org/apache/camel/main/KameletMain.java    | 17 +++++++++
 5 files changed, 84 insertions(+), 7 deletions(-)

diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/ContextServiceLoaderPluginResolver.java
 
b/core/camel-api/src/main/java/org/apache/camel/spi/ContextServiceLoaderPluginResolver.java
new file mode 100644
index 00000000000..4e49e02cc92
--- /dev/null
+++ 
b/core/camel-api/src/main/java/org/apache/camel/spi/ContextServiceLoaderPluginResolver.java
@@ -0,0 +1,41 @@
+/*
+ * 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.spi;
+
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.StatefulService;
+
+/**
+ * Service Provider Interface (SPI) for discovering and loading {@link 
ContextServicePlugin} implementations during
+ * CamelContext initialization.
+ * <p>
+ * This resolver is responsible for automatically discovering and loading 
plugins that extend Camel's functionality
+ * through the Java ServiceLoader mechanism. Implementations of this interface 
participate in the Camel service
+ * lifecycle and are typically invoked during CamelContext startup to 
initialize third-party components and extensions.
+ * <p>
+ * The plugin resolution process typically occurs after the CamelContext has 
been created and configured but before
+ * routes are started, ensuring that all plugins have the opportunity to 
modify or extend the context as needed.
+ * <p>
+ * Implementations must be stateful services that can be started and stopped 
as part of the normal Camel lifecycle, and
+ * they must be aware of the CamelContext they are operating on.
+ *
+ * @see ContextServicePlugin
+ * @see CamelContextAware
+ * @see StatefulService
+ */
+public interface ContextServiceLoaderPluginResolver extends CamelContextAware, 
StatefulService {
+}
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index eec78125a9d..c1504785ea5 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -70,7 +70,6 @@ import org.apache.camel.ShutdownRunningTask;
 import org.apache.camel.StartupListener;
 import org.apache.camel.StartupStep;
 import org.apache.camel.StartupSummaryLevel;
-import org.apache.camel.StatefulService;
 import org.apache.camel.Suspendable;
 import org.apache.camel.SuspendableService;
 import org.apache.camel.TypeConverter;
@@ -106,6 +105,7 @@ import org.apache.camel.spi.CliConnectorFactory;
 import org.apache.camel.spi.ComponentNameResolver;
 import org.apache.camel.spi.ComponentResolver;
 import org.apache.camel.spi.ConfigurerResolver;
+import org.apache.camel.spi.ContextServiceLoaderPluginResolver;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatResolver;
 import org.apache.camel.spi.DataType;
@@ -350,7 +350,7 @@ public abstract class AbstractCamelContext extends 
BaseService
      * Called during object construction to initialize context plugins
      */
     protected void initPlugins() {
-        camelContextExtension.addContextPlugin(StatefulService.class, 
createContextServiceLoaderPlugin());
+        
camelContextExtension.addContextPlugin(ContextServiceLoaderPluginResolver.class,
 createContextServiceLoaderPlugin());
         camelContextExtension.addContextPlugin(StartupConditionStrategy.class, 
createStartupConditionStrategy());
         camelContextExtension.addContextPlugin(CamelBeanPostProcessor.class, 
createBeanPostProcessor());
         
camelContextExtension.addContextPlugin(CamelDependencyInjectionAnnotationFactory.class,
@@ -2383,6 +2383,23 @@ public abstract class AbstractCamelContext extends 
BaseService
             startupStepRecorder.endStep(step5);
         }
 
+        // Start context service loader plugin to discover and load 
third-party plugins early in build phase
+        ContextServiceLoaderPluginResolver contextServicePlugin
+                = 
camelContextExtension.getContextPlugin(ContextServiceLoaderPluginResolver.class);
+        if (contextServicePlugin != null) {
+            try {
+                StartupStep step6 = 
startupStepRecorder.beginStep(CamelContext.class, null, "Start 
ContextServiceLoaderPlugin");
+                ServiceHelper.startService(contextServicePlugin);
+                startupStepRecorder.endStep(step6);
+            } catch (Exception e) {
+                LOG.warn("Cannot start context service loader plugin due: {}. 
Third-party context plugins may not be loaded.",
+                        e.getMessage());
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("", e);
+                }
+            }
+        }
+
         // Call all registered trackers with this context
         // Note, this may use a partially constructed object
         CamelContextTracker.notifyContextCreated(this);
@@ -4473,7 +4490,7 @@ public abstract class AbstractCamelContext extends 
BaseService
 
     protected abstract StartupConditionStrategy 
createStartupConditionStrategy();
 
-    protected abstract StatefulService createContextServiceLoaderPlugin();
+    protected abstract ContextServiceLoaderPluginResolver 
createContextServiceLoaderPlugin();
 
     protected abstract BackOffTimerFactory createBackOffTimerFactory();
 
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextServiceLoaderPlugin.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextServiceLoaderPlugin.java
index 5bcb73f65d5..41840bd68eb 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextServiceLoaderPlugin.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultContextServiceLoaderPlugin.java
@@ -20,6 +20,7 @@ import java.util.ServiceLoader;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.spi.ContextServiceLoaderPluginResolver;
 import org.apache.camel.spi.ContextServicePlugin;
 import org.apache.camel.support.service.ServiceSupport;
 
@@ -40,7 +41,7 @@ import org.apache.camel.support.service.ServiceSupport;
  * @see ContextServicePlugin
  * @see ServiceLoader
  */
-public class DefaultContextServiceLoaderPlugin extends ServiceSupport 
implements CamelContextAware {
+public class DefaultContextServiceLoaderPlugin extends ServiceSupport 
implements ContextServiceLoaderPluginResolver {
     private CamelContext camelContext;
 
     /**
@@ -57,7 +58,8 @@ public class DefaultContextServiceLoaderPlugin extends 
ServiceSupport implements
      */
     @Override
     protected void doStart() throws Exception {
-        ServiceLoader<ContextServicePlugin> contextServicePlugins = 
ServiceLoader.load(ContextServicePlugin.class);
+        ServiceLoader<ContextServicePlugin> contextServicePlugins = 
ServiceLoader.load(ContextServicePlugin.class,
+                camelContext.getApplicationContextClassLoader());
         for (ContextServicePlugin plugin : contextServicePlugins) {
             plugin.load(camelContext);
         }
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index 8b2ec46a60c..0430cfdc7fe 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -25,7 +25,6 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.RouteTemplateContext;
-import org.apache.camel.StatefulService;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.console.DevConsoleRegistry;
@@ -47,6 +46,7 @@ import org.apache.camel.spi.CliConnectorFactory;
 import org.apache.camel.spi.ComponentNameResolver;
 import org.apache.camel.spi.ComponentResolver;
 import org.apache.camel.spi.ConfigurerResolver;
+import org.apache.camel.spi.ContextServiceLoaderPluginResolver;
 import org.apache.camel.spi.DataFormatResolver;
 import org.apache.camel.spi.DeferServiceFactory;
 import org.apache.camel.spi.DumpRoutesStrategy;
@@ -757,7 +757,7 @@ public class SimpleCamelContext extends 
AbstractCamelContext {
     }
 
     @Override
-    protected StatefulService createContextServiceLoaderPlugin() {
+    protected ContextServiceLoaderPluginResolver 
createContextServiceLoaderPlugin() {
         return new DefaultContextServiceLoaderPlugin();
     }
 
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index 95a48ebb021..9abc0c6cf10 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -89,6 +89,7 @@ import org.apache.camel.spi.CliConnector;
 import org.apache.camel.spi.CliConnectorFactory;
 import org.apache.camel.spi.CompileStrategy;
 import org.apache.camel.spi.ComponentResolver;
+import org.apache.camel.spi.ContextServiceLoaderPluginResolver;
 import org.apache.camel.spi.DataFormatResolver;
 import org.apache.camel.spi.FactoryFinder;
 import org.apache.camel.spi.FactoryFinderResolver;
@@ -534,6 +535,7 @@ public class KameletMain extends MainCommandLineSupport {
                 }
             }
         }
+
         configure().withProfile(profile);
 
         // embed HTTP server if port is specified
@@ -732,6 +734,21 @@ public class KameletMain extends MainCommandLineSupport {
             throw RuntimeCamelException.wrapRuntimeException(e);
         }
 
+        // Start the context service loader plugin after all dependencies and 
downloaders are set up
+        // This ensures the classpath is enhanced and ServiceLoader can 
discover third-party plugins
+        ContextServiceLoaderPluginResolver contextServicePlugin = answer
+                
.getCamelContextExtension().getContextPlugin(ContextServiceLoaderPluginResolver.class);
+        if (contextServicePlugin != null) {
+            try {
+                // force start context service loader plugin to discover and 
load third-party plugins
+                ServiceHelper.startService(contextServicePlugin);
+            } catch (Exception e) {
+                LOG.warn(
+                        "Cannot start context service loader plugin due: {}. 
Third-party context plugins may not be loaded.",
+                        e.getMessage());
+            }
+        }
+
         return answer;
     }
 

Reply via email to