Grails won't read external config file? - grails

I'm on Windows 7. Inside my Grails (2.3.6) app's Config.groovy file I have:
grails.config.locations = [
"file:/etc/myapp/env.groovy"
]
// fizz.buzz is defined inside env.groovy
println "fizz.buzz=${fizz.buzz}"
At the root of my D:\ drive:
etc/
myapp/
env.groovy
When I run grails -Dgrails.env=local run-app I get the following output:
fizz.buzz=[:]
What's going on here? Why can't Grails find my env.groovy file and/or read its properties?
My permissions:
Running File('/etc/myapp/env.groovy').absolutePath in the Groovy Console, I get:
Exception thrown
groovy.lang.MissingMethodException: No signature of method: ConsoleScript2.File() is
applicable for argument types: (java.lang.String) values: [/etc/myapp/env.groovy]
Possible solutions: find(), find(groovy.lang.Closure), use([Ljava.lang.Object;),
with(groovy.lang.Closure), is(java.lang.Object), wait()
I also tried running my app and passing in the value for fizz.buzz on the command line via a switch like so:
grails -Dgrails.env=local -Dfizz.buzz="true" run-app
The result was the same. Is it possible that the configs ARE being read in, but are just not available (caching, etc.) at the time that the println is running inside Config.groovy?

Related

SilverStripe running tests using Behat throwing "No behat.yml found for module silverstripe/framework" error

I am working on a SilverStripe project. I am trying to write Behavioural Tests using Behat for my projects. But I am getting an error when I run the tests. Following is what I have done so far.
First I install the module using composer
composer require --dev silverstripe/behat-extension
I have the behat.yml file right under the project root folder with the following definition
default:
suites: []
extensions:
SilverStripe\BehatExtension\MinkExtension:
default_session: facebook_web_driver
javascript_session: facebook_web_driver
facebook_web_driver:
browser: chrome
wd_host: "http://127.0.0.1:9515"
browser_name: chrome
SilverStripe\BehatExtension\Extension:
bootstrap_file: vendor/silverstripe/cms/tests/behat/serve-bootstrap.php
screenshot_path: %paths.base%/artifacts/screenshots
retry_seconds: 4 # default is 2
Then I tried to run the tests executing the following command.
vendor/bin/behat #framework
Then I get the following error.
In ModuleSuiteLocator.php line 166:
No behat.yml found for module silverstripe/framework
behat [-s|--suite SUITE] [-f|--format FORMAT] [-o|--out OUT] [--format-settings FORMAT-SETTINGS] [--init] [--namespace NAMESPACE] [--lang LANG] [--name NAME] [--tags TAGS] [--role ROLE] [--story-syntax] [-d|--definitions DEFINITIONS] [--snippets-for [SNIPPETS-FOR]] [--snippets-type SNIPPETS-TYPE] [--append-snippets] [--no-snippets] [--strict] [--order ORDER] [--rerun] [--stop-on-failure] [--dry-run] [--] [<module> [<paths>]]
There is not behat.yml in the vendor/silverstripe/framework folder. Actually, it is supposed to come with the framework. But it is not there. How can I solve the error?
For all SilverStripe modules the tests and associated configuration are not shipped with distributable packages (e.g. tags).
If you want to use them, you'll need to install the "dev" version. E.g. 4.5.x-dev instead of ~4.5.0.

symfony/yaml backed symfony/config not parsing environment variables

I have recreated a simple example in this tiny github repo. I am attempting to use symfony/dependency-injection to configure monolog/monolog to write logs to php://stderr. I am using a yaml file called services.yml to configure dependency injection.
This all works fine if my yml file looks like this:
parameters:
log.file: 'php://stderr'
log.level: 'DEBUG'
services:
stream_handler:
class: \Monolog\Handler\StreamHandler
arguments:
- '%log.file%'
- '%log.level%'
log:
class: \Monolog\Logger
arguments: [ 'default', ['#stream_handler'] ]
However, my goal is to read the path of the log files and the log level from environment variables, $APP_LOG and LOG_LEVEL respectively. According to The symphony documentations on external paramaters the correct way to do that in the services.yml file is like this:
parameters:
log.file: '%env(APP_LOG)%'
log.level: '%env(LOGGING_LEVEL)%'
In my sample app I verified PHP can read these environment variables with the following:
echo "Hello World!\n\n";
echo 'APP_LOG=' . (getenv('APP_LOG') ?? '__NULL__') . "\n";
echo 'LOG_LEVEL=' . (getenv('LOG_LEVEL') ?? '__NULL__') . "\n";
Which writes the following to the browser when I use my original services.yml with hard coded values.:
Hello World!
APP_LOG=php://stderr
LOG_LEVEL=debug
However, if I use the %env(VAR_NAME)% syntax in services.yml, I get the following error:
Fatal error: Uncaught UnexpectedValueException: The stream or file "env_PATH_a61e1e48db268605210ee2286597d6fb" could not be opened: failed to open stream: Permission denied in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107 Stack trace: #0 /var/www/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array) #1 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\Handler\AbstractProcessingHandler->handle(Array) #2 /var/www/vendor/monolog/monolog/src/Monolog/Logger.php(532): Monolog\Logger->addRecord(100, 'Initialized dep...', Array) #3 /var/www/html/index.php(17): Monolog\Logger->debug('Initialized dep...') #4 {main} thrown in /var/www/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107
What am I doing wrong?
Ok you need a few things here. First of all you need version 3.3 of Symfony, which is still in beta. 3.2 was the released version when I encountered this. Second you need to "compile" the environment variables.
Edit your composer.json with the following values and run composer update. You might need to update other dependencies. You can substitute ^3.3 with dev-master.
"symfony/config": "^3.3",
"symfony/console": "^3.3",
"symfony/dependency-injection": "^3.3",
"symfony/yaml": "^3.3",
You will likely have to do this for symfony/__WHATEVER__ if you have other symfony components.
Now in you're code after you load your yaml configuration into your dependency container you compile it.
So after you're lines here (perhaps in bin/console):
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . DIRECTORY_SEPARATOR . '..'));
$loader->load('services.yml');
Do this:
$container->compile(true);
Your IDE's intellisense might tell you compile takes no parameters. That's ok. That's because compile() grabs its args indirectly via func_get_arg().
public function compile(/*$resolveEnvPlaceholders = false*/)
{
if (1 <= func_num_args()) {
$resolveEnvPlaceholders = func_get_arg(0);
} else {
. . .
}
References
Github issue where this was discussed
Pull request to add compile(true)
Using this command after loading your services.yaml file should help.
$containerBuilder->compile(true);
given your files gets also validated by the checks for proper configurations which this method also does. The parameter is $resolveEnvPlaceholders which makes environmental variables accessible to the yaml services configuration.

Grails 3 JNDI datasource for Tomcat, Weblogic, Glassfish - Vs Grails 2

I'm experimenting with migrating from Grails 2 to Grails 3.
In Grails 2, I used this as my JNDI name within datasource.groovy file, within the Production-env
jndiName = "${(System.getProperty('catalina.home') && (System.getProperty('java.class.path')).trim().toLowerCase().indexOf('tomcat') > 0 ) ? 'java:comp/env/' : ''}jdbc/myGrails"
I found that worked well for me for Glassfish, Weblogic, and Tomcat.
However, when i try this in Grails 3, within the application.yml:
jndiName: ${(System.getProperty('catalina.home') && (System.getProperty('java.class.path')).trim().toLowerCase().indexOf('tomcat') > 0 ) ? 'java:comp/env/' : ''}jdbc/myGrails
I get this error when running "grails run-app":
| Error Error occurred running Grails CLI: mapping values are not allowed here
in 'reader', line 123, column 169:
... mcat') > 0 ) ? 'java:comp/env/' : ''}jdbc/traxGrails
^
(Use --stacktrace to see the full trace)
If I do use this in Grails 3:
jndiName: java:/comp/env/jdbc/myGrails
Then it works fine when using Grails run-app, and also works fine to deploy the WAR to Tomcat.
Can someone help me in getting my "jndi expression" from Grails 2 to work in Grails 3?
It looks like you're trying to use groovy syntax in a yml file, which does not work. You can create an application.groovy file (which will be merged with the application.yml file) if you want to use groovy syntax.
Also take a look at the many ways spring-boot allows you to inject properties via env variables, properties, yml, etc. http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

What classspath is used for executing Grails' application.groovy

What classspath is used for compiling/executing Grails' application.groovy?
In my application.groovy, I instantiate a custom class (contained in a dependency's jar) and assign it to one of the config properties, like so:
environments {
production {
configProperty = new com.example.CustomClass()
I recently upgraded my application from Grails 3.1.5 to 3.2.2, and now this no longer works.
I receive an error like the following when I try to run grails run-app:
Error occurred running Grails CLI: startup failed:
script14788250424471597489853.groovy: 43: unable to resolve class com.example.CustomClass
# line 43, column 33.
configProperty = new com.example.CustomClass()
(Notice that the code is in the production block, but I'm running in development (run-app). That makes me think it's the compilation of this script that is failing.)
So I'm guessing I just need to add my dependency (that contains the CustomClass) to the appropriate classpath, but I'm not sure which one.
I'm using gradle, and have the following in my build.gradle file, to pull in the dependency containing CustomClass:
buildscript {
dependencies {
classpath "com.example:custom-module:1.1"
// ...
dependencies {
compile group: 'com.example', name: 'custom-module', version:'1.1'
}
The grails-app/conf/application.groovy file shouldn't reference application classes because it is read before compilation. If you wish to reference application classes in configuration please use grails-app/conf/runtime.groovy

Running jshint with Rhino shell using configure option

According to GitHub JSHint,
Configuration File Support For Rhino Wrapper #704 issues was closed and support for configuration file was provided [https://github.com/jshint/jshint/issues/704]
I am using Rhino1_7R4 and jshint-rhino-2.5.2.js
Trying to execute this cmd line -
java -jar rhino.jar jshint.js samplefile.js --configure=config.json
but none of the options I specified in the config file seems to take effect.
This is my config.json file:
{
"maxerr" : 150,
"asi" : true,
"expr" : true
}
Also, when trying to specify multiple options via command line, only the first one seems to take effect.
java -jar rhino.jar jshint.js samplefile.js asi=true expr=true
Thanks for your help!

Resources