Saturday, December 18, 2010

Grails and external configuration - the easy way

Hi folks!

This time we're going to work towards the ability to change application's configuration after deployment. In spring what you usually do is allow for loading some settings from a configuration file first prior to setting the defaults. This way once a particular key has been set in the override it's not going to be overridden by the defaults in your applicationContext.xml or beans.xml (however you wanna call it).

In Grails thanks to the existence of another mechanism we can do it differently. We can instruct Grails to load overrides if they have been declared in either the system properties for currently running process (using the -D notation in JAVA_OPTS) or plain in environment options.

The first option is dead simple. What you need to do is to go to your conf/Config.groovy and uncomment the following lines near the top of the file (at least in the original one):
if(System.properties["${appName}.config.location"]) {
grails.config.locations << "file:" + System.properties["${appName}.config.location"]
}

Unfortunately when you do that and set the proper setting during the invocation of java process that started your application (that'd be Tomcat) you'll be presented with an error message like this:
log4j:ERROR Error initializing log4j: No signature of method: 
groovy.util.ConfigObject.leftShift() is applicable for argument
types: (java.lang.String) values: [file:]
Possible solutions: leftShift(java.util.Map$Entry), leftShift(java.util.Map)
groovy.lang.MissingMethodException: No signature of method:
groovy.util.ConfigObject.leftShift() is applicable for argument types:
(java.lang.String) values: [file:]
Possible solutions: leftShift(java.util.Map$Entry), leftShift(java.util.Map)
at Config.run(Config.groovy:17)
2010-12-18 22:30:46 org.apache.catalina.core.StandardContext start
SEVERE: Error listenerStart
2010-12-18 22:30:46 org.apache.catalina.core.StandardContext start
SEVERE: Context [/] startup failed due to previous errors

This is due to the fact that the grails.config.locations element is not set by default. To fix this simply add the following line just before the the code you've just uncommented:

grails.config.locations = []

Once that's done you're able to specify the additional config location in JAVA_OPTS and live is good :)

The other option is to change the predefined code to look for an environment variable instead:

if(System.getenv()["${appName}.config.location"]) {
grails.config.locations << "file:" + System.getenv()["${appName}.config.location"]
}

This way instead of looking for parameters specified via the -D option while invoking the Java virtual machine it'll look for an environment variable.

Surely you'll find more ways to specify the config file location. The beauty of this solution lies in diversity :)

I hope it'll help someone!

Grails 1.3.6 is here!

Hi folks!

Grails 1.3.6 is here and kicks ass again with one of the coolest features ever! The "run-script" command :)

I admit it has been possible for some time now as mentioned on some blogs but actually having it as part of the framework is a kick-ass productivity boost for anyone that needs to perform administrative tasks on regular basis!

Besides the feature mentioned above it is imperative that you check out the externalized configuration options possibility. This time I'll just simply say "finally"! This stuff has been missing from the framework for a long time! I know it was possible to implement override from an external configuration file but the way it looks now is just as it should be from the beginning!

Fantastic job Grails team! Thank you very very much!

Tuesday, December 14, 2010

Grails Routing plugin released!

Hi all,

Today I've released the first version of grails-routing plugin. It's a modernized version of the original grails-camel plugin by Chris Navta with some extras included.

First of all, if you plan to target Apache Camel 1.6.x this plugin is no good for you as it works only with 2.4.0. It's been ages since 1.6 was released and the original author did not express interest in providing an update.

Secondly there are 2 exciting features included:

- integration with grails-quartz plugin to allow jobs to send messages
- integration with Ivy to download all the necessary dependencies

As I am not leaving my audience without ready-to-use examples (by definition) you'll also find 3 of those:

- basic usage example
- Quartz plugin integration example
- ActiveMQ usage example

I hope it'll serve you well!

Sunday, December 5, 2010

Grails vs JSF - 6 months summary

Hi there folks!

I's been exactly 6 months since I left my previous team where I've had to endure JSF programming for more than a year. Starting July 6 this year I moved to another team where I was finally able to choose the technology I want to work with.

Here are some facts you might find interesting when choosing the web framework:

1. JSF.

- previous project status: in progress...
- team size: 4 developers, 1 architect (doing nothing but breaking the code and managing people since he is the official manager for the team), 2 QAs (doing nothing because of how JSF works)
- project size: too big; needs refactoring into smaller pieces.
- project complexity: waaaaay to high; needs refactoring into smaller pieces.
- code coverage: less than 20%; needs improvement.
- current project status: STILL NOT COMPLETED, 6 developers, 1 and the same architect, don't know about the QAs, but one of them loudly complains he doesn't want to have anything to do with this app :D
- overall experience: I hate my job and I want to die

2. Grails

- team size: 1 developer in the role of architect, QA and programmer and 1 database master, separate manager that does what she(!) is supposed to do which is to help people and not to kill their productivity!
- project size: a lot smaller
- project complexity:
UI: 4/10
server side: 2/10
- project releases from ground zero: 3 (this was a green field project)
- code coverage: constantly between 88% and 98%
- overall experience: I love my job again!

So if you think you're one of the great software architects and you don't need to code because there are others to do that: QUIT YOUR JOB AND STOP DOING ANY MORE DAMAGE!!!
And if you still consider JSF to be a viable option: change your profession! You're probably better of in politics :)

Man, I needed to get that out of my chest :D I'm feeling lucky!

Monday, November 29, 2010

Grails, plugins and tags with templates

Hi all,

If you've wondered if it's possible to render a view from a tag I rush to say it is absolutely possible. You just use the render method and specify the template to be rendered like in this example:
class ExampleTagLib {
def example = { attr, body ->
out << render(template: '/tags/example')
}
}

Ok, that was easy. However things get a little bit more interesting when we try to do the same thing from within a plugin. The problem here is that the render method tries to find the view to be rendered in the application and not in the plugin.
The remedy to this problem is simple: you need to append the plugin name as a parameter to the render method like this:
class ExampleTagLib {
def example = { attr, body ->
out << render(template: '/tags/example', plugin: 'example-plugin')
}
}

Here you can find a ready-to-run example.

Have fun!

Friday, November 26, 2010

STS and Grails - running JUnit tests from IDE

Hi folks!

Have you been wondering how to run JUnit 4 tests under STS so that the the tests are recognized and executed properly?

junit.framework.AssertionFailedError: No tests found in

I guess most of you writing tests for your Grails application have seen this one under Idea or STS. The IDE just doesn't see the right tests by itself... But there's hope!

Here's a definition of a class that when used in conjunction with the @RunWith annotation allows the IDE to run those test properly:
package com.aplaline.example.test;

import org.codehaus.groovy.grails.test.GrailsTestTargetPattern;
import org.codehaus.groovy.grails.test.junit4.runner.GrailsTestCaseRunner;

@SuppressWarnings("rawtypes")
public class GrailsJUnit4Runner extends GrailsTestCaseRunner {
public GrailsJUnit4Runner(Class testClass) {
super(testClass, new GrailsTestTargetPattern[0]);
}
}

And here's an example test that uses it:
package com.aplaline.example

import grails.test.*

import org.junit.Test;
import org.junit.runner.RunWith;
import com.aplaline.example.test.GrailsJUnit4Runner;

@RunWith(GrailsJUnit4Runner)
class CalculatorServiceTests extends GrailsUnitTestCase {
@Test
void canAddTwoNumbers() {
// given
def service = new CalculatorService()

// when
def actual = service.sum(1, 2)

// then
assert actual == 3
}
}

See - that wasn't hard, was it?

I hope it'll help you out test your code more efficiently :)

Have fun!!!

Grails, Quartz and JavaMelody

Hi there!

It was just another day, just another app... And yet another Spring gotcha that took 4 hours of my life away...

Let's start from the beginning.

We wanted to add Quartz scheduler to our existing app. The application was monitored from the beginning using the grails-melody plugin. All was nice and dandy right up to the point where we wanted to have the jobs displayed in the monitoring page.

The reason it was not displayed was that the Spring thingy that creates the scheduler is not a straight up implementation of the basic usage of Quartz pattern but it added one nasty thing to it: whenever a job is created it is removed from the central registry. I can't stress that enough that the path of least resistance has been sooo broken here!

What added to the disaster was that the guys that created the Quartz plugin forgot to make the necessary configuration option available to turn the misfeature off.

Result: it's just impossible to see monitoring of jobs in a humane way!

Here's what you need to do to make it work again (nasty hack - you've been warned!):

1. in GrailsMelodyConfig.groovy add the following line:

javamelody.'quartz-default-listener-disabled' = true

2. in spring/resources.groovy copy the imports and the definition of the following beans:

quartzJobFactory, quartzScheduler

3. copy the loadQuartzConfig private method and the line "def config = loadQuartzConfig()" from the QuartzGrailsPlugin.groovy

4. add the exposeSchedulerInRepository = true setting to quartzScheduler

That does the trick but it's as ughly as it gets.

Here's a working example.

I've submitted a bug report to the guys that maintain the Quartz plugin so that they make the necessary extension so that the infernal exposeSchedulerInRepository parameter is configurable.

Have fun!