grailslog4jdatasourcegrails-plugingrails-3.0

Grails - grails.config.locations don't work with classpath and .properties file


I am doing an application with Grails 2.5.3 version. I want to outsource the database code and the section of Log4j.

The code of Log4j is in a external .groovy file. This file won't be modified by user so it is not necessary to be a properties file in /classes dir. The best in the case of database code is to have several features in a external properties file because will continue being a properties file in /classes dir. Also, DataSource.groovy exists with the rest of the configuration.

Then, I have only achieved to work Log4j conf with:

grails.config.locations = ["file:./grails-app/conf/LogConfig.groovy"]

With classpath doesn't work though I put the file in /grails-app/conf dir. This doesn't work:

grails.config.locations = ["classpath:LogConfig.groovy"]

Also, I have added both cases (run-app and war mode). However, when I run grails prod war and deploy Tomcat, Logconfig.groovy is not recognize.

grails.config.locations = ["file:./grails-app/conf/LogConfig.groovy",
"classpath:LogConfig.groovy"]

And in the case of database code, I didn't achieve to work the .properties file. This file I put in grails-app/conf and its contain is:

# DB properties
dataSource.username = xxx
dataSource.password = xxx
dataSouce.driverClassName = xxx
environments.development.dataSource.url = jdbc:mysql://localhost/xxx
environments.test.dataSource.url = jdbc:mysql://localhost/xxx
environments.production.dataSource.url = jdbc:mysql://localhost/xxx

I have read many tutorial and blogs and I don't know how I can do it to work.

Thanks for the help.


Solution

  • How we do it in the development and production mode.

    your-application/
        conf/
            dev/
            qa/
            prod/
        grails-app/
            conf/
              Config.groovy
    

    Config.groovy in the grails-app directory:

    environments {
    
        development {
            grails.logging.jul.usebridge = true
    
            grails.config.locations = [
              "file:conf/dev/XXXConfig.groovy",
              "file:conf/dev/XXXDataSource.groovy",
              "file:conf/dev/XXXLog4JConfig.groovy",
              "file:conf/dev/plugins/XXXSecurityConfig.groovy",
            ]        
        }
        production {
            grails.logging.jul.usebridge = false
    
            grails.config.locations = [
              "classpath:XXXConfig.groovy",
              "classpath:XXXDataSource.groovy",
              "classpath:XXXLog4JConfig.groovy",
              "classpath:plugins/XXXSecurityConfig.groovy",
            ]
        }
    }
    

    For deployments in the application server (Tomcat, Websphere etc) you have to just ADD THE DIRECTORY WHERE CONFIGURATION FILES ARE TO THE CLASSPATH. When you have your configuration file directory in the classpath everything works fine.

    For example we run Tomcat and have startup scripts that do export configuration -directory to the classpath.

    For Grails 3.x I wrote support for this grails.config.locations because they removed the feature and I don't want to change how we do the configs. So put your grails.config.locations -configurations to the application.groovy in the grails-app/conf -directory.

    import org.grails.core.io.DefaultResourceLocator
    import org.springframework.core.env.Environment
    import grails.boot.config.GrailsAutoConfiguration
    import org.springframework.core.env.MapPropertySource
    
    class ApplicationConfigurationLoader {
    
        private ApplicationConfigurationLoader() {}
    
        public static load(GrailsAutoConfiguration application, Environment environment) {
            if (application && environment) {
                DefaultResourceLocator resourceLocator = new DefaultResourceLocator()
                def applicationGroovy = application.getClass().classLoader.getResource('application.groovy')
                if (applicationGroovy) {
                    def applicationConfiguration = new ConfigSlurper(grails.util.Environment.current.name).parse(applicationGroovy)
                    for (String configLocation in applicationConfiguration.grails.config.locations) {
                        def configurationResource = resourceLocator.findResourceForURI(configLocation)
                        if (configurationResource) {
                            def config = new ConfigSlurper(grails.util.Environment.current.name).parse(configurationResource.getURL())
                            environment.propertySources.addFirst(new MapPropertySource(configLocation, config))
                        }
                    }
                }
            }
        }
    }
    

    And in your grails-app/init -folder you have your Application.groovy

    import grails.boot.GrailsApp
    import grails.boot.config.GrailsAutoConfiguration
    
    import org.springframework.core.env.Environment
    import org.springframework.context.EnvironmentAware
    
    import com.bcbmedical.bfw.core.util.ApplicationConfigurationLoader
    
    class Application extends GrailsAutoConfiguration implements EnvironmentAware {
        static void main(String[] args) {
            GrailsApp.run(Application, args)
        }
    
        @Override
        void setEnvironment(Environment environment) {
            ApplicationConfigurationLoader.load(this, environment)
        }
    
    }