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

gnodet 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 ea330029ad30 CAMEL-23686: Fix dev profile overriding user properties 
(#23769)
ea330029ad30 is described below

commit ea330029ad30abf2901faaee5e3f18b6738fa416
Author: Guillaume Nodet <[email protected]>
AuthorDate: Thu Jun 4 20:41:13 2026 +0200

    CAMEL-23686: Fix dev profile overriding user properties (#23769)
    
    The dev profile unconditionally set messageHistory=true (and other
    settings) via ProfileConfigurer, overriding any explicit user
    configuration like camel.main.messageHistory=false.
    
    This caused a critical memory issue with pooled exchanges in dev mode:
    DefaultMessageHistory instances accumulated unbounded (2.95M instances,
    236MB) because message history was forced on regardless of user settings.
    
    Changes:
    - ProfileConfigurer now checks autoConfiguredProperties to skip settings
      the user explicitly configured
    - DefaultConfigurationConfigurer applies messageHistory and
      sourceLocationEnabled unconditionally (not only when true)
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
---
 .../org/apache/camel/main/BaseMainSupport.java     |  3 +-
 .../camel/main/DefaultConfigurationConfigurer.java |  8 +--
 .../org/apache/camel/main/ProfileConfigurer.java   | 71 ++++++++++++++--------
 3 files changed, 49 insertions(+), 33 deletions(-)

diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java 
b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index f83a49000d27..c78b59f6fa50 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -617,7 +617,8 @@ public abstract class BaseMainSupport extends BaseService {
         // configure the profile with pre-configured settings
         step = recorder.beginStep(BaseMainSupport.class, "configureMain", 
"Profile Configure");
         doInitFileConfigurations(camelContext, mainConfigurationProperties);
-        ProfileConfigurer.configureMain(camelContext, 
mainConfigurationProperties.getProfile(), mainConfigurationProperties);
+        ProfileConfigurer.configureMain(camelContext, 
mainConfigurationProperties.getProfile(), mainConfigurationProperties,
+                autoConfiguredProperties);
         recorder.endStep(step);
 
         // configure main listener
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index ad5dbd32cdd8..1021e1789ba4 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -352,12 +352,8 @@ public final class DefaultConfigurationConfigurer {
         
camelContext.getGlobalEndpointConfiguration().setBridgeErrorHandler(config.isEndpointBridgeErrorHandler());
         
camelContext.getGlobalEndpointConfiguration().setLazyStartProducer(config.isEndpointLazyStartProducer());
 
-        if (config.isMessageHistory()) {
-            camelContext.setMessageHistory(true);
-        }
-        if (config.isSourceLocationEnabled()) {
-            camelContext.setSourceLocationEnabled(true);
-        }
+        camelContext.setMessageHistory(config.isMessageHistory());
+        
camelContext.setSourceLocationEnabled(config.isSourceLocationEnabled());
 
         camelContext.setTracing(config.isTracing());
         camelContext.setTracingStandby(config.isTracingStandby());
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/ProfileConfigurer.java 
b/core/camel-main/src/main/java/org/apache/camel/main/ProfileConfigurer.java
index e9d7873a2265..25576a5ed01a 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/ProfileConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/ProfileConfigurer.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.main;
 
+import java.util.Properties;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.ManagementStatisticsLevel;
 import org.slf4j.Logger;
@@ -33,11 +35,13 @@ public class ProfileConfigurer {
     /**
      * Configures camel-main to run in given profile
      *
-     * @param camelContext the camel context
-     * @param profile      the profile
-     * @param config       the main configuration
+     * @param camelContext   the camel context
+     * @param profile        the profile
+     * @param config         the main configuration
+     * @param autoConfigured properties that were explicitly configured by the 
user (may be null)
      */
-    public static void configureMain(CamelContext camelContext, String 
profile, MainConfigurationProperties config) {
+    public static void configureMain(
+            CamelContext camelContext, String profile, 
MainConfigurationProperties config, Properties autoConfigured) {
         if (profile == null || profile.isBlank()) {
             // no profile is active
             return;
@@ -72,17 +76,19 @@ public class ProfileConfigurer {
             config.securityConfig().setPolicy("fail");
         }
 
-        configureCommon(camelContext, profile, config);
+        configureCommon(camelContext, profile, config, autoConfigured);
     }
 
     /**
      * Configures camel in general (standalone, quarkus, spring-boot etc) to 
run in given profile
      *
-     * @param camelContext the camel context
-     * @param profile      the profile
-     * @param config       the core configuration
+     * @param camelContext   the camel context
+     * @param profile        the profile
+     * @param config         the core configuration
+     * @param autoConfigured properties that were explicitly configured by the 
user (may be null)
      */
-    public static void configureCommon(CamelContext camelContext, String 
profile, DefaultConfigurationProperties<?> config) {
+    public static void configureCommon(
+            CamelContext camelContext, String profile, 
DefaultConfigurationProperties<?> config, Properties autoConfigured) {
         camelContext.getCamelContextExtension().setProfile(profile);
 
         if (profile == null || profile.isBlank()) {
@@ -91,23 +97,30 @@ public class ProfileConfigurer {
         }
 
         if ("dev".equals(profile)) {
-            // always enable developer console as it is needed by 
camel-cli-connector
-            config.setDevConsoleEnabled(true);
-            // and enable a bunch of other stuff that gives more details for 
developers
-            config.setCamelEventsTimestampEnabled(true);
-            config.setLoadHealthChecks(true);
-            config.setSourceLocationEnabled(true);
-            config.setModeline(true);
-            config.setLoadStatisticsEnabled(true);
-            config.setMessageHistory(true);
-            config.setInflightRepositoryBrowseEnabled(true);
-            config.setMessageSizeEnabled(true);
-            config.setEndpointRuntimeStatisticsEnabled(true);
-            
config.setJmxManagementStatisticsLevel(ManagementStatisticsLevel.Extended);
-            config.setJmxUpdateRouteEnabled(true);
-            config.setShutdownLogInflightExchangesOnTimeout(false);
-            config.setShutdownTimeout(10);
-            config.setStartupRecorder("backlog");
+            // enable developer features as defaults — user properties can 
override any of these
+            setIfNotConfigured(autoConfigured, "camel.main.devConsoleEnabled", 
() -> config.setDevConsoleEnabled(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.camelEventsTimestampEnabled",
+                    () -> config.setCamelEventsTimestampEnabled(true));
+            setIfNotConfigured(autoConfigured, "camel.main.loadHealthChecks", 
() -> config.setLoadHealthChecks(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.sourceLocationEnabled",
+                    () -> config.setSourceLocationEnabled(true));
+            setIfNotConfigured(autoConfigured, "camel.main.modeline", () -> 
config.setModeline(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.loadStatisticsEnabled",
+                    () -> config.setLoadStatisticsEnabled(true));
+            setIfNotConfigured(autoConfigured, "camel.main.messageHistory", () 
-> config.setMessageHistory(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.inflightRepositoryBrowseEnabled",
+                    () -> config.setInflightRepositoryBrowseEnabled(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.messageSizeEnabled", () -> config.setMessageSizeEnabled(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.endpointRuntimeStatisticsEnabled",
+                    () -> config.setEndpointRuntimeStatisticsEnabled(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.jmxManagementStatisticsLevel",
+                    () -> 
config.setJmxManagementStatisticsLevel(ManagementStatisticsLevel.Extended));
+            setIfNotConfigured(autoConfigured, 
"camel.main.jmxUpdateRouteEnabled",
+                    () -> config.setJmxUpdateRouteEnabled(true));
+            setIfNotConfigured(autoConfigured, 
"camel.main.shutdownLogInflightExchangesOnTimeout",
+                    () -> 
config.setShutdownLogInflightExchangesOnTimeout(false));
+            setIfNotConfigured(autoConfigured, "camel.main.shutdownTimeout", 
() -> config.setShutdownTimeout(10));
+            setIfNotConfigured(autoConfigured, "camel.main.startupRecorder", 
() -> config.setStartupRecorder("backlog"));
         }
 
         if ("prod".equals(profile)) {
@@ -119,4 +132,10 @@ public class ProfileConfigurer {
         LOG.info("The application is starting with profile: {}", profile);
     }
 
+    private static void setIfNotConfigured(Properties autoConfigured, String 
key, Runnable setter) {
+        if (autoConfigured == null || !autoConfigured.containsKey(key)) {
+            setter.run();
+        }
+    }
+
 }

Reply via email to