Working on Grails 3 I realized that I no longer can specify external configuration using the standard grails.config.locations
property in Config.groovy
file.
Reason is obvious! There is no Config.groovy
now in Grails 3. Instead we now use application.yml
to configure the properties. However, you can't specify the external configuration using this file too!
What the hack?
Now Grails 3 uses Spring's property source concept. To enable external config file to work we need to do something extra now.
Suppose I want to override some properties in application.yml
file with my external configuration file.
E.g., from this:
dataSource:
username: sa
password:
driverClassName: "org.h2.Driver"
To this:
dataSource:
username: root
password: mysql
driverClassName: "com.mysql.jdbc.Driver"
First I need to place this file in application's root. E.g., I've following structure of my Grails 3 application with external configuration file app-config.yml
in place:
[human@machine tmp]$ tree -L 1 myapp
myapp
├── app-config.yml // <---- external configuration file!
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── grails-app
└── src
[human@machine tmp]$
Now, to enable reading this file just add following:
- To your
build.gradle
file
bootRun {
// local.config.location is just a random name. You can use yours.
jvmArgs = ['-Dlocal.config.location=app-config.yml']
}
- To your
Application.groovy
file
package com.mycompany
import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean
import org.springframework.context.EnvironmentAware
import org.springframework.core.env.Environment
import org.springframework.core.env.PropertiesPropertySource
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.Resource
class Application extends GrailsAutoConfiguration implements EnvironmentAware {
static void main(String[] args) {
GrailsApp.run(Application, args)
}
@Override
void setEnvironment(Environment environment) {
String configPath = System.properties["local.config.location"]
Resource resourceConfig = new FileSystemResource(configPath)
YamlPropertiesFactoryBean ypfb = new YamlPropertiesFactoryBean()
ypfb.setResources([resourceConfig] as Resource[])
ypfb.afterPropertiesSet()
Properties properties = ypfb.getObject()
environment.propertySources.addFirst(new PropertiesPropertySource("local.config.location", properties))
}
}
Notice that Application
class implements EnvironmentAware
Interface and overrides its setEnvironment(Environment environment):void
method.
Now this is all what you need to re-enable external config file in Grails 3 application.
Code and guidance is taken from following links with little modification:
- http://grails.1312388.n4.nabble.com/Grails-3-External-config-td4658823.html
- https://groups.google.com/forum/#!topic/grails-dev-discuss/_5VtFz4SpDY
Cheers!!!
@javagrails as a point.
After "grails war" that "app-config.yml" file wont be inside the war or the deployed directory, and the configuration will not be loaded.
There is a workaround to that: on "src/main" directory create other dir named "resources" (src/main/resources) and put the configuration file (app-config.yml) there.
On Application.groovy class Load the file with this:
Like that u will be able to load the external configuration file in production and development mode.