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;
}