CAMEL-9789: Avoid starting services to soon during CamelContext startup, that 
can trigger circular dependencies issue with Spring and similar IoC frameworks.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cda77f81
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cda77f81
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cda77f81

Branch: refs/heads/master
Commit: cda77f81624467a658a31dd83476bcac7e14b475
Parents: 596d1a1
Author: Claus Ibsen <davscl...@apache.org>
Authored: Wed Apr 6 15:24:08 2016 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Thu Apr 7 09:39:40 2016 +0200

----------------------------------------------------------------------
 .../java/org/apache/camel/CamelContext.java     | 22 ++++++++++-
 .../apache/camel/impl/DefaultCamelContext.java  | 39 ++++++++++----------
 2 files changed, 41 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cda77f81/camel-core/src/main/java/org/apache/camel/CamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/CamelContext.java 
b/camel-core/src/main/java/org/apache/camel/CamelContext.java
index c7d212f..9ace5a7 100644
--- a/camel-core/src/main/java/org/apache/camel/CamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java
@@ -29,6 +29,7 @@ import 
org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
 import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
 import org.apache.camel.api.management.mbean.ManagedRouteMBean;
 import org.apache.camel.builder.ErrorHandlerBuilder;
+import org.apache.camel.impl.DeferServiceStartupListener;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
@@ -231,6 +232,25 @@ public interface CamelContext extends SuspendableService, 
RuntimeConfiguration {
     void addService(Object object, boolean stopOnShutdown) throws Exception;
 
     /**
+     * Adds a service to this context.
+     * <p/>
+     * The service will also have {@link CamelContext} injected if its {@link 
CamelContextAware}.
+     * The service will also be enlisted in JMX for management (if JMX is 
enabled).
+     * The service will be started, if its not already started.
+     * <p/>
+     * If the option <tt>closeOnShutdown</tt> is <tt>true</tt> then this 
context will control the lifecycle, ensuring
+     * the service is stopped when the context stops.
+     * If the option <tt>closeOnShutdown</tt> is <tt>false</tt> then this 
context will not stop the service when the context stops.
+     *
+     * @param object the service
+     * @param stopOnShutdown whether to stop the service when this 
CamelContext shutdown.
+     * @param forceStart whether to force starting the service right now, as 
otherwise the service may be deferred being started
+     *                   to later using {@link #deferStartService(Object, 
boolean)}
+     * @throws Exception can be thrown when starting the service
+     */
+    void addService(Object object, boolean stopOnShutdown, boolean forceStart) 
throws Exception;
+
+    /**
      * Removes a service from this context.
      * <p/>
      * The service is assumed to have been previously added using {@link 
#addService(Object)} method.
@@ -259,7 +279,7 @@ public interface CamelContext extends SuspendableService, 
RuntimeConfiguration {
     <T> T hasService(Class<T> type);
 
     /**
-     * Defers starting the service until {@link CamelContext} is started and 
has initialized all its prior services and routes.
+     * Defers starting the service until {@link CamelContext} is (almost 
started) or started and has initialized all its prior services and routes.
      * <p/>
      * If {@link CamelContext} is already started then the service is started 
immediately.
      *

http://git-wip-us.apache.org/repos/asf/camel/blob/cda77f81/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 7e7dce1..a8ff760 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -1218,11 +1218,12 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
     }
 
     public void addService(Object object, boolean stopOnShutdown) throws 
Exception {
-        doAddService(object, stopOnShutdown);
+        doAddService(object, stopOnShutdown, false);
     }
 
-    private void doAddService(Object object, boolean stopOnShutdown) throws 
Exception {
-        doAddService(object, stopOnShutdown, false);
+    @Override
+    public void addService(Object object, boolean stopOnShutdown, boolean 
forceStart) throws Exception {
+        doAddService(object, stopOnShutdown, forceStart);
     }
 
     private void doAddService(Object object, boolean stopOnShutdown, boolean 
forceStart) throws Exception {
@@ -2344,7 +2345,7 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
                 typeConverter = createTypeConverter();
                 try {
                     // must add service eager and force start it
-                    doAddService(typeConverter, true, true);
+                    addService(typeConverter, true, true);
                 } catch (Exception e) {
                     throw ObjectHelper.wrapRuntimeCamelException(e);
                 }
@@ -2356,8 +2357,8 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
     public void setTypeConverter(TypeConverter typeConverter) {
         this.typeConverter = typeConverter;
         try {
-            // must add service eager
-            doAddService(typeConverter, true, true);
+            // must add service eager and force start it
+            addService(typeConverter, true, true);
         } catch (Exception e) {
             throw ObjectHelper.wrapRuntimeCamelException(e);
         }
@@ -3001,23 +3002,23 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
         // and we needed to create endpoints up-front as it may be accessed 
before this context is started
         endpoints = new DefaultEndpointRegistry(this, endpoints);
         // add this as service and force pre-start them
-        doAddService(endpoints, true, true);
-        // special for executorServiceManager as want to stop it manually
-        doAddService(executorServiceManager, false, true);
-        doAddService(producerServicePool, true, true);
-        doAddService(pollingConsumerServicePool, true, true);
-        doAddService(inflightRepository, true, true);
-        doAddService(asyncProcessorAwaitManager, true, true);
-        doAddService(shutdownStrategy, true, true);
-        doAddService(packageScanClassResolver, true, true);
-        doAddService(restRegistry, true, true);
-        doAddService(messageHistoryFactory, true, true);
+        addService(endpoints, true, true);
+        // special for executorServiceManager as want to stop it manually so 
false in stopOnShutdown
+        addService(executorServiceManager, false, true);
+        addService(producerServicePool, true, true);
+        addService(pollingConsumerServicePool, true, true);
+        addService(inflightRepository, true, true);
+        addService(asyncProcessorAwaitManager, true, true);
+        addService(shutdownStrategy, true, true);
+        addService(packageScanClassResolver, true, true);
+        addService(restRegistry, true, true);
+        addService(messageHistoryFactory, true, true);
 
         if (runtimeEndpointRegistry != null) {
             if (runtimeEndpointRegistry instanceof EventNotifier) {
                 getManagementStrategy().addEventNotifier((EventNotifier) 
runtimeEndpointRegistry);
             }
-            doAddService(runtimeEndpointRegistry, true, true);
+            addService(runtimeEndpointRegistry, true, true);
         }
 
         // eager lookup any configured properties component to avoid 
subsequent lookup attempts which may impact performance
@@ -3059,7 +3060,7 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
         if (streamCachingInUse) {
             // stream caching is in use so enable the strategy
             getStreamCachingStrategy().setEnabled(true);
-            doAddService(getStreamCachingStrategy(), true, true);
+            addService(getStreamCachingStrategy(), true, true);
         } else {
             // log if stream caching is not in use as this can help people to 
enable it if they use streams
             log.info("StreamCaching is not in use. If using streams then its 
recommended to enable stream caching."

Reply via email to