How to set Set Vm Arguements for Grails 2.2.4 - grails

I am using Grail 2.2.4,
in conf/spring/resources.xml, I try to import a file as ${realm}-config.properties, where realm is a vm arguement, I tried to set vm arguements in BuildConfig.groovy as below
grails.tomcat.jvmArgs = ["-Dstage=dev","-Drealm=app"]
But it doesn't seem to pick up. I get below error,
class path resource [${realm}-config.properties] cannot be opened because it does not exist
What is the right way to set vm arguements in grails 2.2.4 ?

Maybe try to load your config via environment variable handled in conf/Config.groovy
def ENV_NAME = "MY_CONFIG"
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)
}

Related

Launch grails command from grails application

I am trying to run a grails command like "grails help" from a Grails application but all the tries I have done end up with "Error: Could not find or load main class org.codehaus.groovy.grails.cli.support.GrailsStarter".
Basically, I have tried
def p1 = "grails help".execute()
p1.waitFor()
println "return code: ${ p1.exitValue()}"
println "stderr: ${p1.err.text}"
println "stdout: ${p1.in.text}"
Also:
Runtime runtime = Runtime.getRuntime()
Process process = runtime.exec("grails help")
process.waitFor()
println "return code: ${ process.exitValue()}"
println "stderr: ${process.err.text}"
println "stdout: ${process.in.text}"
And finally:
def sout = new StringBuffer()
def serr = new StringBuffer()
final processBuilder = new ProcessBuilder()
processBuilder.directory(new File("/myFolder"))
processBuilder.command(["grails","help"])
println processBuilder.directory()
Process proc = processBuilder.start()
proc.consumeProcessOutput(sout, serr)
def status = proc.waitFor()
println 'sout: ' + sout
println 'serr: ' + serr
Of course, the "grails help" command is not the one I want to execute but fixing this one it will fix the one I need to run.
Any other ideas?
If I create a new app with grails 2.3.5 (grails create-app script-test), then declare a controller (grails create-controller test.Run) and change it so it looks like:
package test
class RunController {
def index() {
def t = [ 'grails', 'help' ].execute().text
render "<pre>$t</pre>"
}
}
Then run it with grails run-app, and go to localhost:8080/script-test/run, I get the grails help screen rendered as text to the web-page.
The problem you are going to have is that this won't work in production as you are probably going to deploy a war file, so grails won't be aware of where you are, or what you are doing (if indeed grails is installed on the server)
I think you need to re-think your strategy, whatever it is you are trying to do :-(

Grails External configuration Config System.getenv

i have code in config.groovy
def ENV_NAME = "/home/myFolder"
if(System.getenv("ENV_NAME")) {
println( "Including configuration file: " + System.getenv("ENV_NAME"));
grails.config.locations << "file:" + System.getenv("ENV_NAME")
} else {
println "No external configuration file defined."
}
When I run, the result is "No external configuration file defined."
What do I miss?
Presumably that there isn't an environment variable named ENV_NAME defined at the point when you ran the app.

externalizing configurations for test.datasource

I have been able externalize DataSource configurations for development environment by updating grails.config.locations in Config.groovy and then setting specific configurations in .grails/${appName}-config.properties as following:
dataSource.driverClassName = com.mysql.jdbc.Driver
dataSource.url = jdbc:mysql://localhost/db-dev
dataSource.username = root
dataSource.password = pass
For the 'test' environment, i have different Database so i would like to updated test.dataSource.url accordingly but this doesn't work. It still takes the 'dev' dataSource.url when running 'grails test' mode(i.e. grails test dgm-update). How to externalize test environment DataSource configuration?
Thank You for helping
grails.config.locations = ["file:${userHome}/.grails/${appName}-config-${grails.util.Environment.current.name}.properties"]
and then put nested files for each env:
/home/me/.grails/myapp-config-dev.properties
/home/me/.grails/myapp-config-test.properties
/home/me/.grails/myapp-config-production.properties
Try to use Groovy external configuration, i.e. ".grails/${appName}-config.groovy" with environment specific DSL:
environments {
test {
dataSource {
...
}
}
}

externalizing grails config into multiple properties files from environment variable

I have setup an environment variable like this:
APP_HOME = "c:\app\app-datasource.properties
in config.groovy I do
def ENV_NAME = "APP_HOME"
if(!grails.config.location || !(grails.config.location instanceof List)) {
grails.config.location = []
}
if(System.getenv(ENV_NAME)) {
println "Including configuration file specified in environment: " + System.getenv(ENV_NAME);
grails.config.location << "file:" + System.getenv(ENV_NAME)
} else if(System.getProperty(ENV_NAME)) {
println "Including configuration file specified on command line: " + System.getProperty(ENV_NAME);
grails.config.location << "file:" + System.getProperty(ENV_NAME)
} else {
println "No external configuration file defined."
}
I got this from a post online, I want to know if we need to use grails.config.location or grails.config.locations ?
Also instead of APP_HOME being set to the properties file directly, can I set it to a directory path (e.g.: c:\apps) and then can I have multiple properties files placed in that directory, then if I do the following multiple times will it work?:
grails.config.locations << "file:" + System.getProperty(ENV_NAME)+ "\app-datasource.properties"
grails.config.locations << "file:" + System.getProperty(ENV_NAME)+ "\app-reporting.properties"
and so on...
Thanks in advance
You need to modify grails.config.locations (plural). My (very limited) experience says that the external files are probably not loaded until after Config.groovy is completed.
You might want to consider looking for he additional configuration file on your classpath; then you can put your extra outside of the Grails project (e.g., in your web server's library) or within the grails-app/conf directory. I have written the instructions on how to do that here.
Here's a post on how to do it from a plugin: https://stackoverflow.com/a/9789506/1269312

grails configure log4j without rebuilding war?

This seems pretty strange, but when grails builds a war file it doesn't generate a log4j.properties or log4j.xml file.
Instead it has the following in WEB-INF/web.xml
web.xml:
<listener>
<listener-class>org.codehaus.groovy.grails.web.util.Log4jConfigListener</listener-class>
</listener>
and apparently "grails Log4j DSL configures logging in-memory". The problem here is - log4j isn't automatically exposed to JMX for us to dynamically change and there's no log4j file generated by grails. But Config.groovy is a compiled file.
There's got to be an easy way to manage this without rebuilding the war?
One option suggested is go through to spring and configure logging there:
resources.groovy:
beans = {
log4jConfigurer(org.springframework.beans.factory.config.MethodInvokingFactoryBean)
{
targetClass = "org.springframework.util.Log4jConfigurer"
targetMethod = "initLogging"
arguments = ["classpath:myapp/log4j.properties"]
}
}
then shift the configuration in the DSL to the configured file.
Can anyone advise the 'groovy' way to dynamically change logging configuration without rebuilding the WAR file each time. Using grails-1.3.7. Cutting the DSL out doesn't seem the right way.
Thanks
You may have an external config file that is searched for by your application at startup time.
You would have a MyExternalConfig.groovy file somewhere in your production environment. For example:
log4j = {
def catalinaBase = System.properties.getProperty('catalina.base')
if (!catalinaBase) catalinaBase = '.'
def logDirectory = "${catalinaBase}/logs"
appenders {
rollingFile name:"infoLog", maxFileSize:'900KB', file:"${logDirectory}/${appName}Info.log", maxBackupIndex:10, layout:pattern(conversionPattern: '%d{DATE} %p %c - %m%n'), threshold: org.apache.log4j.Level.INFO
rollingFile name:"erroLog", maxFileSize:'900KB', file:"${logDirectory}/${appName}Erro.log", maxBackupIndex:10, layout:pattern(conversionPattern: '%d{DATE} %p %c - %m%n'), threshold: org.apache.log4j.Level.ERROR
}
root {
info 'infoLog', 'erroLog'
additivity = false
}
error erroLog:"StackTrace"
error erroLog: 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'net.sf.ehcache.hibernate'
warn infoLog: 'org.mortbay.log'
info infoLog: "grails.app"
}
Then in your Config.groovy file, that belongs to your grails project in conf folder, you put this as the last thing of the file:
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 configuration file defined."
}
This will look for external configurations files to add to your grails.config.locations attribute of your Config.groovy. First it looks for it as a System Environment variable (I use it this way), if it does not find, then it looks for a command line parameter (so you could add it when you start your tomcat app, as a parameter to startup.sh).
To configure your system environment variabble, just do this before starting tomcat:
MY_EXTERNAL_CONFIG="/home/tomcat/configs/MyExternalConfig.groovy"
export MY_EXTERNAL_CONFIG
--- start tomcat here ---
That's it.

Resources