You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@grails.apache.org by "weinellucian (via GitHub)" <gi...@apache.org> on 2026/07/06 08:15:49 UTC

[I] Grails 7 Holders.config.merge() issue in tomcat when multiple Grails 7.1.0 Apps are deployed in apache-tomcat-10.1.50 [grails-core]

weinellucian opened a new issue, #15840:
URL: https://github.com/apache/grails-core/issues/15840

   ### Expected Behavior
   
   We are encountering an issue with Holders.config.merge() in Grails 7.1.0 when multiple Grails applications are deployed on the same Apache Tomcat 10.1.50 instance.
   The problem does not occur when only a single Grails application is deployed. The same code has been working reliably in Grails 6.x without any issues.
   Environment
   
   
   **Use Case**
   Our application has a scheduled CRON job that periodically reloads application-specific configuration values from a database.
   The reload process is designed to preserve the original application configuration and then merge it back after refreshing dynamic configuration values.
   The workflow is:
   
   1. Back up the original configuration (initialConfig) that contains values loaded from:
   - application.groovy / application.yml
   - External filesystem configuration
   - Other startup configuration sources
   
   2. Clear the current configuration using:
   -  Holders.config.clear()
   
   3.Restore the original configuration using:
      Holders.config.merge(initialConfig)
   
   **Expected Behavior:**
   
   After calling: **Holders.config.merge(initialConfig)** all configuration entries stored in **initialConfig** should be restored into Holders.config.
   
   This behavior works correctly: in In Grails 6.x, whereas in  Grails 7.1.0 it works  when only a single application is deployed in Tomcat
   if we deploy more than one  Grails 7.1.0  **Holders.config.merge** does not correctly restore the configuration.
   Instead, the application configuration appears to be lost or emptied, leaving **Holders.config** in an invalid state. As a result, application functionality dependent on configuration values ant it stops working
   
   **Configuration Reload Logic**
   
   static PropertySourcesConfig initialConfig = new PropertySourcesConfig()
   backupInitialConfiguration()
   Holders.config.clear()
   // In Grails 7.1.0, when multiple applications are deployed in the same
   // Tomcat instance, this call does not restore the configuration correctly.
   Holders.config.merge(initialConfig)
   
   
   //Backup Logic 
   
   public void backupInitialConfiguration() {
       if (initialConfig?.size() == 0) {
           Config config = Holders.config
           Map<Object, Object> configMap = [:]
   
           for (def entry : config) {
               configMap.put(entry.key, config.get(entry.key))
           }
   
           initialConfig = new PropertySourcesConfig(configMap)
       }
   }
   
   
   
   ### Actual Behaviour
   
   Mentioned in above section
   
   ### Steps To Reproduce
   
   It's mentioned in "Expected Behavior" Section 
   
   ### Environment Information
   
   Grails Version: 7.1.0
   Tomcat Version: 10.1.50
   Deployment Model: Multiple Grails applications deployed in the same Tomcat instance
   Java Version:  JDK 17 and Above 
   
   ### Example Application
   
   _No response_
   
   ### Version
   
   7.1.0


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@grails.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Grails 7 Holders.config.merge() issue in tomcat when multiple Grails 7.1.0 Apps are deployed in apache-tomcat-10.1.50 [grails-core]

Posted by "jdaugherty (via GitHub)" <gi...@apache.org>.
jdaugherty commented on issue #15840:
URL: https://github.com/apache/grails-core/issues/15840#issuecomment-6029417939

   @weinellucian I've opened https://github.com/apache/grails-core/pull/16547


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@grails.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Grails 7 Holders.config.merge() issue in tomcat when multiple Grails 7.1.0 Apps are deployed in apache-tomcat-10.1.50 [grails-core]

Posted by "matrei (via GitHub)" <gi...@apache.org>.
matrei commented on issue #15840:
URL: https://github.com/apache/grails-core/issues/15840#issuecomment-6031663768

   @weinellucian I could reproduce the empty restore on 7.1.0 with a single app as soon as `spring.profiles.active` is set as a JVM system property: the backup created with `new PropertySourcesConfig(configMap)` is already empty, and after `clear()`/`merge()` the config is `[:]`. Since system properties are shared by all apps in the same Tomcat, that is likely what triggers it in your setup. #16547 should fix this regression. But I'd also recommend moving away from clearing and re-merging `Holders.config` at runtime:
   
   - `clear()` followed by `merge()` is not atomic. The config is backed by a plain `LinkedHashMap`, so while the job runs, request threads can see an empty or half-merged config.
   - Many values are copied out of the config once at startup (`@Value`, `@ConfigurationProperties`, `GrailsConfigurationAware`, plugin bean definitions, datasource settings). Those won't pick up reloaded values anyway, so only code that calls `config.getProperty(...)` on every use sees the changes.
   - It relies on internal merge semantics, which is how this broke between 6 and 7.
   
   A small settings service addresses these. Keep the database values in an immutable snapshot, swap it in a single assignment, and fall back to the static config for anything not stored in the database:
   
   ```groovy
   import grails.core.GrailsApplication
   import grails.gorm.transactions.Transactional
   
   class SettingsService {
   
       GrailsApplication grailsApplication
   
       private volatile Map<String, String> settings = Collections.emptyMap()
   
       String getSetting(String key) {
           settings.containsKey(key) ? settings[key] : grailsApplication.config.getProperty(key)
       }
   
       @Transactional(readOnly = true)
       void reload() {
           var loaded = [:] as Map<String, String>
           AppSetting.list().each { loaded[it.name] = it.settingValue }
           settings = Collections.unmodifiableMap(loaded)
       }
   }
   ```
   
   Call `settingsService.reload()` from `BootStrap` and from your cron job, and read dynamic values through `settingsService.getSetting(...)` instead of `Holders.config`. Readers always see either the old snapshot or the new one, never an empty config, and `application.yml`/external config stay untouched, so there is nothing to back up and restore.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@grails.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] Grails 7 Holders.config.merge() issue in tomcat when multiple Grails 7.1.0 Apps are deployed in apache-tomcat-10.1.50 [grails-core]

Posted by "weinellucian (via GitHub)" <gi...@apache.org>.
weinellucian commented on issue #15840:
URL: https://github.com/apache/grails-core/issues/15840#issuecomment-4928594693

   Can anyone help us on this JIRA


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@grails.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org