I am trying to load the properties file externally, by setting up the system environment.
In my config.groovy file,
println "Config file location --->" + System.getenv("SAM_ENV")
grails.config.locations = ["file:"+ System.getenv("SAM_ENV")]
I have set the system env SAM_ENV value as C:\test\config.properties.
When I try to run the application,I am getting the print value as
Config file location ---> C:\test\config.properties prints properly.
The problem is when I try to access the properties file in my controller as
print "PAGINATION1"+grailsApplication.config.PAGINATION1
the value of PAGINATION1 is not getting printed properly.
Can any one help me what configuration has to be done to access the external properties file in grails application.
Add the below line in config.groovy
grails.config.locations = [ "classpath:grails-app-config.properties"]
environments {
development {
grails.logging.jul.usebridge = true
grails.config.locations = ["file:C:\\conf\\externalfile.groovy"]
}
production {
grails.logging.jul.usebridge = false
grails.config.locations = ["file:/opt/config/externalfile.groovy"]
// TODO: grails.serverURL = "http://www.changeme.com"
}
}
If you want to access any property from external configuration(config.groovy) then just declare the property like
property = property value eg:(ImagePath = "C:\\Users\\Saved Pictures")
access it like grailsApplication.config."property"
eg:(grailsApplication.config.ImagePath)
NOTE: dont use def just a property and its value.
What you're looking for is extending the classpath, which you can achieve by adding a post compilation event in _Events.groovy. Try this:
eventCompileEnd = {
ant.copy(todir:classesDirPath) {
fileset(file:"C:\test\config.properties")
}}
You can find more help here
Related
In my Config.groovy I have:
// Lots of other stuff up here...
environments {
development {
myapp.port = 7500
}
production {
myapp.port = 7600
}
}
fizz {
buzz {
foo = "Port #${myapp.port}"
}
}
When I run my app via grails -Dgrails.env=development run-app, my web app spins up without errors, but then at runtime I see that the value of fizz.buzz.foo is "Port #[:]". I would expect it to be "Port #7500".
Why isn't Grails seeing my var?
You could probably get away with this if myapp.port were not in an environments block but that's a side effect of the way Config.groovy is processed rather than being intentional. And if you were to override myapp.port in an external config file then fizz.buzz.foo would still end up with the value from Config.groovy, not the override from the external.
You could make it a late-binding GString using a closure to pull the value from grails.util.Holders.config when fizz.buzz.foo is referenced rather than when it is defined:
foo = "Port #${-> Holders.config.myapp.port}"
This is different from "Port #${Holders.config.myapp.port}" which would attempt to access the config at the point where Config.groovy is being parsed.
If the value you're defining here is one that will ultimately end up defining a property of a Spring bean (for example many of the spring-security-core plugin configuration options become bean properties) then you may be able to do
foo = 'Port #${myapp.port}'
with single rather than double quotes. This causes the resulting config entry to contain the literal string ${myapp.port}, which will be resolved against the config by the Spring property placeholder mechanism when it is used as a bean property value.
Another way is to simply use variables within your config file like this:
def appPort = 7500
environments {
production {
appPort = 7600
myapp.port = appPort
}
}
fizz {
buzz {
foo = "Port #$appPort"
}
}
And also, you don't need to send the -Dgrails.environment=development when you execute the run-app, it's the default one.
In my config.groovy my dev environment is...
development {
...
grails.resources.mappers.yuicssminify.disable = true
grails.resources.mappers.yuijsminify.disable = true
grails.resources.mappers.hashandcache.disable = true
grails.resources.mappers.zip.disable = true
}
When I run grails dev war from jenkins I want an extra property in some cases. This property is:
grails.plugin.jbossas.removeLog4jJars = false
I cannot alter the development environment in the Config.groovy. Is there any way I can pass in this extra property?
I think the cleanest solution would be a new environment for your jenkins:
jenkins {
grails.plugin.jbossas.removeLog4jJars = false
}
If this is not an option (like mentioned in the comments) it is also possible to move this configuration value into a system specific property file:
grails.config.locations = ["file:/home/user/my-config.properties"]
Within my-config.properties on the jenkins system you can do:
grails.plugin.jbossas.removeLog4jJars = false
The my-config.properties files of other systems stay empty (I think they don't even need to exist).
If this is also not an option you can do something (not so nice) like this:
development {
if (MyUtils.isJenkins()) {
grails.plugin.jbossas.removeLog4jJars = false
}
...
}
Within MyUtils.isJenkins() you have to determine on which system your application is running. For example:
class MyUtils {
public static boolean isJenkins() {
def env = System.getenv()
return env[IS_JENKINS]
}
}
This example checks if the system variable IS_JENKINS is set (you can add other ways to determine on which system you are running like)
In my Config.groovy I consolidate properties files in the following way:
grails.config.locations << "file:${userHome}/environment.properties" << "file:${userHome}/passwords.properties"
I have two problems:
When autowiring in the Service layer, with GrailsApplication I can retrieve properties defined in Config.groovy BUT NOT those properties defined in the files
I cannot autowire GrailsApplication in my Jobs (using Quartz plugin)
Can anyone shed light on these issues?
What I do is to have an external Config.groovy file, for instance: MyConfig.groovy
At the end of the standard grails Config.groovy file, I have the following:
def ENV_NAME = "MY_EXTERNAL_CONFIG"
if(!grails.config.locations || !(grails.config.locations instanceof List)) {
grails.config.locations = []
}
if(System.getenv(ENV_NAME)) {
grails.config.locations << "file:" + System.getenv(ENV_NAME)
} else if(System.getProperty(ENV_NAME)) {
grails.config.locations << "file:" + System.getProperty(ENV_NAME)
} else {
println "No external Configs found."
}
So now you can have a MyConfig.groovy file anywhere in production environment (for example) and then set an Environment system variable to point to this file (or pass it as parameter to startup.sh), before you start tomcat:
MY_EXTERNAL_CONFIG="/home/tomcat/configs/MyConfig.groovy"
export MY_EXTERNAL_CONFIG
That's it. Now you have an external MyConfig.groovy file. The properties in it are accessible from your grails app as they were part of the standard Config.groovy
import org.codehaus.groovy.grails.commons.*
//...
ConfigurationHolder.config.foo.bar.hello
how about trying this!(just a guess, it should not make any difference! however give it a shot and let me know if doesnt work!)
grails.config.locations = [ "file:${userHome}/environment.properties",
"file:${userHome}/passwords.properties" ]
I have an application where the config is externalized. In Config.groovy, I'm updating
grails.config.locations=[file:/.../myapp-log4j.groovy, file:/.../myapp-config.properties]
That works fine for datasources and such. But later in Config.groovy, I have:
springws {
wsdl {
MyApp {
// In this case the wsdl will be available at <grails.serverURL>/services/v1/myapp/myapp-v1.wsdl
wsdlName= 'myapp-v1'
xsds= '/WEB-INF/myapp.xsd'
portTypeName = 'myappPort'
serviceName = 'myappService'
locationUri = "${grails.serverURL}/services/v1/myapp"
targetNamespace = 'http://www..../myapp/v1/definitions'
}
}
}
And ${grails.serverURL} contains [:] which is not what is in my config file. The config file contains (among the datasource details):
grails.serverURL=http://samiel:9011/xid
My guess would be that the updated grails.config.locations is only used after I return from Config.groovy.
So, what are my options to setup my web service details based on the externalized serverURL ?
This is what I get when I run your example (just confirming your starting postion):
def testExternalConfig() {
println "grails.serverURL: ${ConfigurationHolder.config.grails.serverURL}"
println "springws.wsdl.MyApp.locationUri ${ConfigurationHolder.config.springws.wsdl.MyApp.locationUri}"
}
--Output from testExternalConfig--
grails.serverURL: http://samiel:9011/xid
springws.wsdl.MyApp.locationUri http://localhost:8080/soGrails/services/v1/myapp
Like you said, Config.groovy does not see the value set in the external config. I believe that Grails processes external
configs after Config.groovy, and this test appears to confirm that. The logic being that you likely have external config file
values that you want to have precedence over config in war file.
Fix is to override the full property in myapp-config.properties:
grails.serverURL=http://samiel:9011/xid
springws.wsdl.MyApp.locationUri=http://samiel:9011/xid/services/v1/myapp
With that change I get this:
--Output from testExternalConfig--
grails.serverURL: http://samiel:9011/xid
springws.wsdl.MyApp.locationUri http://samiel:9011/xid/services/v1/myapp
I want to add linux based or windows based system properties in Grails as my app needs to run in the both. I know that we can add grails.config.locations location specified in Config. groovy.
But I need the if and esle condition for the file to be picked.
the problem is config.grrovy has userHome grailsHome appName appVersion
I would need something like osName.
Either I can go ahead with syetm.properties or if soembody can tell me how these (only) properties are availble in Config.groovy (through DefaultGrailsApplication or otherwise. that woyuld be great.
Also, somewjhat moer elegant would be if where I need those properties I make my service as user-defined-spring-bean. Would that be right and feasible approach?If yes, some example
You could do something like this in your Config.groovy:
environments {
development {
if (System.properties["os.name"] == "Linux") {
grails.config.locations = [ "file:$basedir/grails-app/conf/linux.properties" ]
} else {
grails.config.locations = [ "file:$basedir/grails-app/conf/windows.properties" ]
}
}
...
}
Alternatively, for a service based approach, you could bundle up all the OS specific behavior into implementations of service interface. For example:
// OsPrinterService.groovy
interface OsPrinterService {
void printOs();
}
// LinuxOsPrinterService.groovy
class LinuxOsPrinterService implements OsPrinterService {
void printOs() { println "Linux" }
}
// WindowsOsPrinterService.groovy
class WindowsOsPrinterService implements OsPrinterService {
void printOs() { println "Windows" }
}
Then instantiate the correct one in grails-app/conf/spring/resources.groovy like so:
beans = {
if (System.properties["os.name"] == "Linux") {
osPrinterService(LinuxOsPrinterService) {}
} else {
osPrinterService(WindowsOsPrinterService) {}
}
}
Then the correct service will be automatically injected into your objects by spring.
Create a custom enviorenment for both Windows and Linux. Something like the following should work if placed in config.groovy
environments {
productionWindows {
filePath=c:\path
}
productionLinux {
filePath=/var/dir
}
}
You should then be able to use the grails config object to get the value of filePath reguardless of weather your on Windows or Linux. For more details on this see section 3.2 of
http://www.grails.org/doc/1.0.x/guide/3.%20Configuration.html If you wanted to create a war file to run on Linux you would execute the following command.
grails -Dgrails.env=productionLinux war
And then to get a file path you stored in config.groovy for the specific environment your running in.
def fileToOpen=Conf.config.filePath
fileToOpen will contain the value you assigned to filePath in your config.groovy based on the environment your currently running as, so when running with productionLinux as the environment it will contain the value /var/dir