Thursday, December 16, 2010

What Do You Want From Your Team

I have been working as an independent consultant on-and-off for the last 6 years, and because of that I got to work with many different companies and management styles. Also being a consultant giving me an unique and almost neutral third-party perspective whenever I work with a company. One interesting observation I made in these years was despite all the time, energy, and training spent in many companies, a lot of the managers don't seem to know what exactly they want from their employees. That sounds too harsh, you might say. Or is it? Let me give you an example. One of a recent email I witnessed from one of the manager in my client's company stated that they want all the employees to start their day and be ready on company IM no later than 9:30am. Ok, it appears like a perfectly reasonable request when you first look at it, however the only problem is the team had an implicit flexible working hour arrangement for months already if not years. So now let us see what exactly does this manager achieved by doing this:


  1. People are going to start their working day earlier however grumpy they are. They might need to negotiate with their spouse to re-arrange their pick up and drop off schedule for their kids. Some might need to switch from public transit to car or vice versa since they now have to join the rest of the city in a mad rush to work every morning.

  2. People who starts early are for sure gonna leave early, so the total number of productive hours per day you get from each employee is not going to change. The only thing this changes is how crowded the subway is when you employee leaves the office.

  3. People might start asking, especially the talented ones in your team, why they rejected that generous offer from a competitor last month, so they can enjoy the daily rush hour?


You might ask “Is it really this bad? All they are asking is for people to be on time.” I admit I might have stretched the reaction a bit, however I can tell you in my experience I have seen number of teams dismembers themselves because something small like this eventually snowballed out of proportion. What I am trying to bring out here is not “Don't ask you employee to come early” but rather as a manager before you ask employee to do anything think about what exactly you want to get from your team. As Archimedes famously said, “Give me a lever and I can move the world.” In our little work society mostly governed by Behavioral Economics, everyone reacts to incentives therefore like some economist would like to say “Give me a proper incentive scheme and I can get anyone to do anything”. This may sound arrogant or even devious, however we should not underestimate the power of incentives in our micro-society at work. In my personal opinion everything a manager/leader does is either an incentive which motivates people towards a common goal or negative-incentive which motivates people to work against the common goal.


Lets take a closer look at this particular manager and the problem he is facing. In reality the problem that he is trying to tackle is loss of productivity as well as lacking predictability in project schedule. He is under a lot of stress delivering a major project for the company, but his team had a bad track records of under delivering and schedule overrun in a form of either massive OT or last minute show stopper or both. Thus what he really wants from his team is improved productivity, predictability, and better quality of work. Now if we also take a look at how the team works:


  1. Team works strictly within a waterfall process with no iteration or even intermediate milestone to serve as check points to prevent last minute breakdown

  2. Most of the developers in the team does not practice any form of unit test but rather code by vague design and imagination

  3. There is very limited daily/weekly status meetings of any sort so everyone is working in their own black box with little knowledge of overall progress until its too late

  4. Architect and designer do not code in this team, and all developers are either contractor or outsourced therefore there is an ever-increasing knowledge gap between people who creates design and people who implements them


Its not hard to find many much better incentives that could have worked in team's favor than the 9:30am start time.



Monday, November 15, 2010

Use Flat Local Folder as Custom Repository for Grails

Currently I am introducing Grails as one of the new web application frameworks to my client in their existing environment, however their environment currently does not rely on Maven or Ivy repository manager to distribute and share their internal libraries but rather checked into version control under one directory flat. To make Grails recognize this flat file folder as one of the dependency repository, we had to configure the BuildConfig script with a custom Ivy resolver. I thought someone else might find its useful if you are dealing with legacy build environment.


// create a custom file based resolver
def libResolver = new org.apache.ivy.plugins.resolver.FileSystemResolver()

// specify common lib directory
def commonLibDir = new File("c:\commonLib")

// specify patterns
libResolver.addArtifactPattern(commonLibDir + "/[artifact]")
libResolver.addIvyPattern(commonLibDir + "/[artifact]")

libResolver.name = "my-repository"

grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
// uncomment to disable ehcache
// excludes 'ehcache'
}
log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
repositories {
grailsPlugins()
grailsHome()
grailsCentral()

resolver libResolver
}
dependencies {
// here the groupid and version are basically ignored since our
// flat lib folder does not maintain such information
compile 'yourcompany:artifact.jar:0.0.0'
}
}

Thursday, August 05, 2010

Q&A on Refactoring and Architecture in Agile

Recently I answered a list of survey questions, on refactoring and evolving architecture in Agile project, from Lianping Chen - a doctoral researcher from Lero, University of Limerick. Here I want to share it with the community and feel free to share your comment and experiences.

1. Have you seen/experienced cases where software architecture emerges successfully from continuous small refactoring?

Yes

2. What are the main reasons that make the emerging of software architecture from continuous small refactoring success, according to your observations/experiences?

Agility in the engineering practice is definitely a must supplemented by the agility in the process as a secondary but important aspect. I also find having a light up-front design to get everybody to agree on a very high level architecture has also been very useful in guiding the refactory. Here when I talk about agility in engineering I refer to implementing the full set of agile practices: unit test, high coverage, continuous integration, refactory, and ideally also TDD and PP, since in my experience all these practice compliment each other, strengthen each other while eliminating the pitfalls that otherwise might be introduced by other practices. For example refactoring without high unit test coverage is more like hacking than engineering since you have no idea whether certain change you make will break other part of the system, and unit test without refactory will definitely introduce rigidity in architecture compounded with light up-front design could contribute to severe and rapid architectural deterioration thus compromise in quality and productivity.

3. Have you seen/experienced cases where architecture failed to emerge from continuous small refactoring?

Yes

4. What are the main reasons that cause such unsuccessful emerging of software architecture from continuous small refactoring, according to your observations/experiences?

It happens actually quite often when you have a team that only practices the process side of the agile methodology, or pick and choose some aspects of the engineering discipline for example only implement refactory but not unit test.

5. Could you please describe some cases/examples of such unsuccessful emerging of software architecture from continuous small refactoring?

...


If it is convenient, could you please also provide the following information?

1. How many years of experience do you have in using agile methods?

7 years

2. Which agile methods (e.g., Scrum, XP) have you used?

Both, and I prefer XP due to the fact many teams in the field that chooses to implement Scrum are the ones who choose to only implement the easy process of Agile but deliberately choose to ignore the hard engineering aspects of Agile

3. Which application domains (e.g., automobiles, telecommunications, finance, medical devices, web-based socio-technical systems, and etc.) you have been working in?

Telco, Online Gaming, and Government

4. What is your definition/understanding of software architecture? (You can refer to a definition you like or give your own understanding.)

I like Ralph Johnson's definition mentioned in XP mail listing:

In most successful software projects, the expert developers working on that project have a shared understanding of the system design. This shared understanding is called ‘architecture.’


In short architecture is a group consensus among expert developers.

One last thing I would like to mention is that initially I always believed any team can adopt Agile practice and be effective, however after almost 8 years of trying to convince and help people adopt Agile I realized that not every team or every one can adopt Agile. To successfully adopt Agile a team has to be:

  • Very experienced (PP lower the requirement of experience a bit since it helps disperse knowledge and train less experienced developer a lot more efficiently)
  • Having an open, blame-free, and trusting environment
  • Deep and thorough understanding on not just the practice of Agile but also the reason behind Agile practice among team members (An Agile coach is required if local expertise lacks in this area)
  • Having management backing and overall Agile adoption even outside of the development context

The most successful Agile adoption in my experience are the ones with all the above quality and combined with top-down support and mandate with bottom-up organic initiatives.

Hope this help a bit, and I am quite interested in your research and findings so once its published I would like to have a copy if possible.

Thursday, July 22, 2010

Griffon Validation Plugin 0.5 Released

I am happy to announce v0.5 release of the Griffon Validation plugin. This release was mainly designed to upgrade Validation plugin to be compatible with Griffon 0.9 core, plus some minor internal clean up. To upgrade your application to this version you need to first upgrade your Griffon installation to 0.9 by:

  1. Download Griffon 0.9 from http://griffon.codehaus.org/Download
  2. Run "griffon upgrade" under your application folder
Then run "griffon install-plugin validation" to upgrade the plugin

Other than the core upgrade, another somewhat important change in this release is now Validation plugin officially depends on i18n plugin, so once you upgrade to v0.5 Griffon will automatically install i18n (currently 0.2) into your application if its not already installed yet.

For more information on GValidation plugin please check out the Wiki page, and as usual please feel free to contact me for any bugs or feature requests.

Tuesday, June 22, 2010

Griffon Validation Plugin 0.4 Release

Just released GValidation plugin 0.4. In this post I would like to highlight some of enhancement and new feature introduced in this release.

1. @Validatable AST Transformation

In the previous version user can enhance regular Groovy class in their Griffon application manually using:

ValidationEnhancer.enhance(object)


With 0.4 release now this manual process can be replace by the convenient @Validatable annotation thanks to Groovy AST transformation. Any class now annotated with @Validatable will be automatically synthesized with validation capability.


import net.sourceforge.gvalidation.annotation.Validatable

@Validatable
class AnnotatedModel {
String id
String email = " "

static constraints = {
id(nullable: false)
email(email: true)
}
}

Other than the fact that annotated class is enhanced during build-time instead of run-time as for the models and manually enhanced objects, they behave identically from user's point-of-view.

2. Bindable errors

In this release the dynamic errors field in models and Validatable objects has been enhanced to be Bindable, hence standard SwingBuilder binding can be utilized to tie errors automatically to a component. This is particularly handy when building error notification component to display error message for the user. For example with this new capability now you can simple bind the error to the build-in ErrorMessagePanel without manually synchronizing it after each validation.


container(new ErrorMessagePanel(messageSource),
id: 'errorMessagePanel', constraints: NORTH,
errors: bind(source: model, 'errors'))


3. beforeValidation callback

Inspired by Rails before_validation callback, now GValidation provides a similar pre-validation callback to give model developer a chance to manipulate data right before validation. Here is an example how this kind of callback can be used:


class ServerModel {
@Bindable String serverName
@Bindable int port
@Bindable String stringForm

def beforeValidation = {
setStringForm "${serverName}:${port}"
}

….
}

For more information please check out the GValidation Wiki Page. As usual your feedback and comment are always welcome.

Wednesday, June 02, 2010

How to support custom artifact type in Griffon plugin

A newer revised version of this guide (compatible with Griffon 0.9.2+) is now available here.


Out-of-box Griffon supports 4 different types of artifacts: Model, View, Controller (MVC) plus Service, these are the major building blocks of Griffon. Just like it's cousin Grails, in Griffon plugins and addons can also introduce new artifact types, however the process is fairly different from what Grails employs. In the recent 0.3 release of the GValidation Plugin a new custom artifact type has been introduced - Constraint, and I would like to share some of my learning here so it would be a little bit easier if you are planning to do something similar.

Step 1 - Handle your artifact

To support a new artifact type you have to tell the Griffon core about the artifact type first. You can achieve this by implementing your own ArtifactHandler, for most of the common cases extending from ArtifactHandlerAdapter will be enough otherwise you can implement the interface manually. Here is what it looks like for the Constraint artifact type:


class ConstraintArtifactHandler extends ArtifactHandlerAdapter {
public static final String TYPE = "constraint"
public static final String TRAILING = "Constraint"

ConstraintArtifactHandler() {
super(TYPE)
}
}


Step 2 - Register your artifact

As shown above, if you have experience working with Grails artefact support, you will notice the handler implementation is almost identical in Griffon, however things starting to differ from this point forward. Now you have the handler implemented, next thing is to register it with Griffon core. This is best achieved during initialization phase in your addon. Open the [PluginName]GriffonAddon.groovy file add the following callback if its not already there:


def addonInit = {app ->
....
app.artifactManager.registerArtifactHandler(new ConstraintArtifactHandler())
....
}


Step 3 - Find your artifacts

Now we have the new artifact type registered, next step is to tell Griffon where to find the artifacts. Ever wonder how Griffon knows to look under griffon-app/models for model classes? This is what we are going to do in this step. This is also where Griffon custom artifact support truly differs from Grails. Instead of handling it at run-time, Griffon chooses to handle this at build time, so to achieve this you need to tap into the Griffon event model. Open the _Events.groovy script and implement the following event listener:


eventCollectArtifacts = { artifactsInfo ->
if(!artifactsInfo.find{ it.type == 'constraint' }) {
artifactsInfo << [type: 'constraint', path: 'constraints', suffix: 'Constraint'] } }


This event listener will tell Griffon to look for anything under griffon-app/constraints folder with suffix 'Constraint' and register them as constraint artifacts.

Step 4 - Measure your artifacts

Now we pretty much have the basic bolts and nuts in place, its time to make our newly found artifact type to be more integrated with Griffon as any other first class artifact types do. One of the nice feature of Griffon is the stats command, it gives you an instant overview of how big your app is in terms of how many files and Line of Code per type including artifacts. Won't it be nice to have it also display the metrics about our own custom artifacts? fortunately its actually pretty easy to achieve in Griffon, similar to the previous step we will add another listener to the _Events script.


eventStatsStart = { pathToInfo ->
if(!pathToInfo.find{ it.path == 'constraints'} ) {
pathToInfo << [name: 'Constraints', path: 'constraints', filetype:['.groovy','.java']] } }


Griffon event model is a very powerful concept, usually when I am not sure how to do something funky in Griffon this is the first place I look.

Step 5 - Automate your artifacts

One of big selling point of the next generation Rails-like RIA framework is the ability to create any artifact simply by using one of the built-in command, for example grails create-controller or griffon create-mvc. To make our new artifact type a true first-class citizen of Griffon, of course we need all the bells and whistles. To add a new command to Griffon, you need to create a new Groovy script under scripts folder:

CreateConstraint.groovy


target('default': "Creates a new constraint") {
depends(checkVersion, parseArguments)

promptForName(type: "Constraint")

def name = argsMap["params"][0]
createArtifact(name: name, suffix: "Constraint", type: "Constraint", path: "griffon-app/constraints")
createUnitTest(name: name, suffix: "Constraint")
}


Like other convention-over-configuration framework, Griffon relies heavily on simple naming conventions, so in the script make sure you naming everything consistent to avoid unnecessary complexity. This script will create artifact for the type of Constriant and related unit test case, as you can see it will be a simple matter to create integration test case if need be.

Now with the command in place, you can finally provide the template for the new artifact being created. Again naming convention is being used to determine where to find template file, for our example the template file should be placed under src/templates/artifacts and named Constraint.groovy:


@artifact.package@class @artifact.name@ {

def validate(propertyValue, bean, parameter) {
// insert your custom constraint logic
}

}


Phew, now finally we are done. This is a long post and as you can see a lot of plumbing; this is exactly why currently there are some discussion going on within Griffon dev mail list to provide declaration based custom artifact support either using Grails style or Groovy AST transformation, so stay tuned for future updates on this topic.

I also need to thank Andres Almiray for pointing me to the right direction when I first started looking into this topic.

Wednesday, May 26, 2010

Griffon Validation Plugin 0.3 Release

I am happy to announce the 0.3 release of GValidation plugin - a Griffon validation plugin designed to provide Grails like constraints and validation support. In this post I would like to introduce a few new features implemented in this release.

1.Custom Constraint Support

This is probably the biggest improvement introduced in this release. Inspired by Grails' Custom Constraint plugin, once upgraded GValidation will introduce a new type of artifact to your Griffon application - Constraint.

In previous version GValidation allows you to define a custom validator using a closure just like in Grails:

// Simple custom validator
even( validator: {
return (it % 2) == 0
})

However this kind of closure based simple validator is hard to reuse therefore you will have to rewrite them every single time, a major inconvenience and a violation of the DRY principle. In version 0.3 now you can create a top level reusable custom constraint by using the following script:

griffon create-constraint [package].[constraint-name]
A Groovy class will be created under griffon-app/constraints folder to allow you to define your custom validation logic, a typical custom constraint looks like this:

class MagicConstraint {

/**
* Generated message
*
* @param propertyValue value of the property to be validated
* @param bean object owner of the property
* @param parameter configuration parameter for the constraint
* @return true if validation passes otherwise false
*/
def validate(propertyValue, bean, parameter) {
if (!parameter)
return true

return propertyValue == 42
}

}

Once created a custom constraint pretty much behaves exactly like a built-in constraint, you can easily invoke them in your model by following the simple naming convention, with the above example you can apply the constraint on any field in your model by using the following declaration:

class DemoModel{
….

@Bindable int magicNumber

static constraints = {
….
magicNumber(magic: true)
….
}
2. Selective Validation

Originally proposed by Andres Almiray, GValidation now offers capability to perform validation on only a selected number of fields in the model instead of all. Here is a typical single field validation usage scenario:

model.validate('name')
...
if(model.hasErrors()){
// notify user
...
}
You can also perform selective validation on a list of fields:

model.validate(['name', 'email'])
...
if(model.hasErrors()){
// notify user
...
}
3. Default Catch-All Error Message Code

This is a minor enhancement however a great time saver for someone who has to perform a large number of validation in their app. In previous version validation plugin only generates model specific error message code:

[modelclass].[field].[validator].message
Now for every built-in and custom validator the plugin will also generate a default error message code additionally:

default.[validator].message

You can retrieve the error code and default error code from the Error object using the following fields respectively:


error.errorCode
error.defaultErrorCode


For a complete guide on the plugin, please check out the Wiki page.

Monday, April 19, 2010

Quote of the Day

Most teams purporting to be doing agile software development are not applying the level of technical rigor necessary to succeed at it. Most "agile" team have actually only adopted Scrum's project-management practice and have failed to effectively adopt "the hard disciplines" like test-driven development, refactoring, pair programming, simple design, and continuous integration.


- Formal Versus Agile: Survival of the Fittest - IEEE Computer 2009 September


Friday, April 16, 2010

Use controller action via listeners in Griffon view (Updated)

I have been asked recently a couple of times about how to use listeners in Griffon view for event handling such as mousePressed or focusLost. Apparently neither Swing builder nor Griffon documented this aspect in details, and it has been a bit confusing for some folks to figure it out since the usage is slightly different from regular actions.

In Griffon view you can supply a predefined action to a component such as JButton to invoke a controller action in a breeze. The following code snippet demonstrate how it is done in Griffon:


actions {
action(id: "quitAction",
name: messageSource.getMessage('menuItem.exit.caption'),
mnemonic: "x",
closure: controller.quit)
}

...

menuBar {
menu(messageSource.getMessage('menu.file.caption')) {
menuItem(quitAction)
}
}

...


From Andres Almiray:

The main difference between all examples is that the first assigns an instance of javax.swing.Action to the node's value. The builder knows that it can configure a button/menuItem/etc out of an Action so it does it.



When it comes to listener and event handling, one would expect a similar pattern applies; for example according to Swing builder documentation mousePressed event exists on JComponent level so one would hope the following code can bind a controller action to an mousePressed event.


actions {
action(id: "nodeSelectionAction",
closure: controller.selectNode)
}

list(id:'nodeList', model: model.serverListModel, eventPressed: nodeSelectionAction)


From Andres Almiray:
The second example does not work because it attempts to assign an instance of javax.swing.Action as the value of the menuPressed property, which has to be a MouseListener. That's why it breaks (although the error text may be misleading).



Unfortunately you will get No such property: mousePressed for class: javax.swing.JList error message. Instead the correct way to do this is by using the closure instead of an Action since mousePressed expects a listener. Groovy closure declared here will be converted to a listener automatically:


list(id:'nodeList', model: model.serverListModel, mousePressed: controller.selectNode)

From Andres Almiray:
The third example works because it assigns a closure as the value of the mousePressed property. Groovy will generate under the covers a proxy of a MouseListener that uses that closure as the implementation of said proxy's mousePressed method.


Hope this post will save some investigation time for someone who is new to Griffon and Swing builder.

Go Griffon!

Tuesday, April 06, 2010

GValidation 0.2 release

After I released the very first version of the Griffon Validation plugin, I have received quite a few positive feedback, and thank everybody for all the feedback. Based on some initial bug report I have fixed some dependency problem with the initial version now the plugin is shipped with all dependencies it requires so you don't need to manually add jars into your project. Currently GValidation depends on:

  • Apache Commons Lang 2.5
  • Apache Commons Validator 1.3.1
  • Jakarta ORO 2.0.8
In the 0.2 release I have also fixed some inconsistency in some of the validator implementation, now all validator except nullable and blank will ignore both null and blank value. In other words, unless you provide nullable or blank validator the validation logic will assume all fields are optional by default.

To upgrade your application to the new plugin version please uninstall validation plugin first:

griffon uninstall-plugin validation
griffon install-plugin validation

I have also updated the Wiki with a quick tutorial showing how validation can be utilized in a simple but somewhat telling example. The same tutorial demo application binary can also be downloaded from the project files page.

Thursday, April 01, 2010

Grails like Validation plugin for Griffon

Recently I am working on a Griffon powered Swing application in one of my open source project Hydra Cache. While really love the convention over configuration setup and the grooviness of swing builder, soon I realized one tool I rely on frequently in Grails is missing in Griffon. Griffon does not tie the model to database via GORM as Grails does, which makes perfect sense since when building rich client application in many cases your model layer is not (or some will argue should not) directly tie to the database, after all that's why the 3-tier architecture was invented in the first place. That's when I start thinking if the convenient declaration based constraint and validation support in Grails can live without GORM but be applied on simple POGO model classes in Griffon. After writing validation listeners on the view a couple of times, my laziness pushed me to create a plugin to do just that. After a few positive and encouraging email exchange on dev@griffon.codehaus.org mail list and a few late night coding session, the first release of GValidation plugin is now ready for your evaluation. The plugin is implemented without dependency on Spring framework and purely implemented in Groovy.

To install the plugin use:

griffon install-plugin validation

Once the plugin is installed the following field and method will be automatically injected into your model classes:


Errors errors
boolean hasErrors()
boolean validation()


Here error field is a Groovy clone of Spring Validation Errors class in order to retain certain API consistency when compared with Grails validation support. Now in a typical scenario you can achieve the generic validation by first declare your constraints in the model:


class PersonModel {
@Bindable String name
@Bindable String email
@Bindable String blog

static constraints = {
name(blank: false)
email(blank: false, email: true)
blog(url: true)
}
}

Then perform the validation, usually in a controller action:



def doSomething = {evt = null ->
if (!model.validate()) {
doLater {
// display error messages
}
} else {
doLater {
// clear error messages
}

doOutside {
// do something interesting
}
}
}


You can also check and manipulate the errors generated by validation method using the errors object directly:



model.validate()
// do something else
..
if(model.hasErrors()){
model.errors.each{error->
// do something with the error
}
}

The only validators that are not ported from Grails are:
  • scale
  • unique
Since they are largely there to influence database schema generation rather than performing actual validation. A new validator inetAddress is introduced to ensure the field is a valid host name or IP address. For a complete list of the built-in validator shipped with this plugin please see the GValidation Wiki.

Just like Grails constraints, you can also implement your custom validator using Groovy closure:



// Simple custom validator
even( validator: {
return (it % 2) == 0
})


// Custom validator with access to the object under validation
password1( validator: {
val, obj ->
obj.properties['password2'] == val
})


// Custom validator with custom error
magicNumber( validator: {
val, obj ->
def result = checkMagicNumber()
if(!result)
obj.errors.rejectValue('magicNumber', 'customErrorCode')
return result
})




And last but not least once installed, GValidation allows you to enhance any POGO object in your application to have validation support, just simply use the ValidationEnhancer with your object:



import net.sourceforge.gvalidation.ValidationEnhancer

ValidationEnhancer.enhance(pogo)

pogo.validate()

poso.errors.each{
println it
}

For more information please check out the Wiki page, and feel free to send me your feedback or suggestion. For bug report please use the Bug Tracker.

Monday, March 29, 2010

Use Grails (GORM) with legacy Oracle 9i database

I am currently consulting on a project with a client who is using the legacy Oracle 9i database with JDK 1.4.2. I have recommended Groovy and Grails for their new enhancement project, however to add some grooviness to this kind of legacy platform introduce some pretty unique challenges. In this post I will attempt to compile a list of hurdles we went through to get Grails working perfectly with the legacy environment.

Grails version


First thing you need to know is that only Grails 1.0.x is compatible with JDK 1.4 so only limited grooviness is available but major improvement nevertheless from our client's existing environment.


Hibernate Dialect


Some of the meta API that Hibernate relies on to pick the right database dialect is not available with 9i so in your DataSource.groovy use the following configuration to specify a dialect manually.


dataSource {
....
driverClassName = "oracle.jdbc.OracleDriver"
dialect = "org.hibernate.dialect.Oracle9iDialect"
....
}


Table Level Mapping


A few thing needs to be configured on pretty much every one of your domain class to work with existing data schema. First map the table to an existing table (most of the legacy table naming convention will not be same as what hibernate expect unless you are extremely lucky ;-), and secondly turn off the optimistic locking so hibernate will not look for the version column on the table. This can be achieved by adding this static mapping field on our GORM domain class.


static mapping = {
table "LEGACYORACLETABLE"
version false
}



ID Generation Strategy

Most likely the legacy database might have some pretty custom ID generation strategy. To have the flexibility to map your domain class id to the legacy column you need to define the id field manually. Normally GORM/Hibernate automatically map the id field for you (usually using bigint or number of some sort) but manually defining it allows you to map it to pretty much any kind of data type.


String id

static mapping = {
id column: 'ENTITYID', generator: 'assigned', type: 'string', sqlType: 'varchar2'
}


We have found keeping the id field for every model class with the default name "id" makes the scaffolding and view generation working for most of the scenarios even with the legacy database, which is a big time saver for us.

For auto increment id with sequence you can rely on the hibernate default sequence, just make sure to create the sequence "hibernate_sequence" before you start the application. Or you can specify your generator using the following mapping:


Long id

static mapping = {
id column: 'ENTITYID', generator: 'sequence', params:[sequence:'custom_seq'], sqlType: 'integer'
}


Install plugins with Grails 1.0.x

The Grails plugin repository has grown tremendously in size, and the out-dated install-plugin script used by Grails 1.0.x does not seems to be able to handle the large list, besides it tries to update the entire plugin list each time which is very time consuming. What we found the best way to install plugin with Grails 1.0.x is by pin down the plugin yourself first, and then just install the plugin using the URL directly. Just make sure the right plugin version is used since not all the plugin works with Grails 1.0.x. All Grails plugins can be found here: http://svn.codehaus.org/grails-plugins/

For example to install Testing plugin (part of Grails core since 1.1) using the following command:
grails install-plugin http://svn.codehaus.org/grails-plugins/grails-testing/trunk/grails-testing-0.5.zip


After this you should be well on your way to unleash some grooviness with your perfectly aged environment. Time to impress the heck out of your boss and revitalize your work environment :D

Wednesday, February 10, 2010

Stub static method on domain class in Grails explained

Since Grails 1.1 the unit test capability has been greatly improved for pretty much anything you can imagine in Grails from domain class to controller even taglibs can be easily tested in plain old junit with the help of GrailsUnitTestCase and many of it's cousins such as ControllerUnitTestCase specialized in different aspects of the framework.

However the fantastic mocking framework is not without its boundary. The mockDomain method provided by GrailsUnitTestCase has its limit, it does not provide the capability to fully mock GORM dynamic finders as well as criteria and executeQuery methods. Luckily the test framework also provide the ability to mock any method regular or static using mockFor() method (details) however it comes short when you have static query method created on domain class. Imagine the following example:


class Foo{
...

static def listAllAwesomeFoo(keyword, params) {
Foo.executeQuery('''select f from Foo as f
inner join f.tags as t
where f.awesome = true and t.keyword = ?''',
[keyword],
params)
}
}

class FooService {
def doSomethingUseful(){
def awesomeFoos = Foo.listAllAwesomeFoo('something', [max:10])
....
}
}


Now to test the FooService you need the ability to stub or mock the Foo.listAllAwesomeFoo() method and since its a static method there is really no easy way to do it even with Grails test framework; or is there? This is where Groovy MOP can save you a lot of grief and time. To stub this kind of static method all you need to do in Groovy is add the following code before your test code:


Foo.metaClass.static.listAllAwesomeFoo = {keyword, params -> [foo1, foo2] }


Thats it. Now you can happily test all your service logic without worrying about stubbing the whole database to run the HQL. Later on you can always isolate and use integration test with in-memory database to test the HQL separately.

Wednesday, February 03, 2010

Create Open Flash Chart in Grails without using plugins

If you are like me tired of outdated Grails plugins and verbose API in Java for Open Flash Chart 2, here is a short demonstration of generating OFC2 using just naked Grooviness. OFC2 charts are driven by JSON data feed, and with Grails' built in JSON converter and support you really don't need another API or plugin to use OFC2. Just download the flash binary and javascript from http://teethgrinder.co.uk/open-flash-chart-2/ and create a controller in your Grails application. Now you have two choices, you can either use the JSON builder in your controller or just plain maps to generate JSON data. I chose plain maps since its easier to manipulate and examine in unit tests, but the JSON builder will work just as well with even more expressive DSL. Here is an example of a simple chart:


def chartData = [
"elements": [ ["type": "line", "values": [ 1, 2, 1] ] ],
"title": [ "text": "Wed Feb 03 2010" ]
]
render chartData as JSON


Now you are free to use the latest OFC binary without worrying about upgrading the plugin or mocking the complex API in your test. The syntax is extremely similar to the JSON output so you can basically learn from checking out the examples on OFC site. Here is a more complicated example with tooltips, on-load animation and custom look-and-feel.


[
'elements': [
["font-size": 10, "text": "Daily Info",
"tip": '$#val#
on #x_label#', "type": "line", "width": 4,
"dot-style": ["type": "dot", "dot-size": 5, "colour": "#DFC329", "tip": '$#val#
on #x_label#'],
'values': values, 'colour': '#8F9CFF', "on-show": ["type": "drop", "delay": 0.5]
]
],
"is_decimal_separator_comma": 0,
"is_fixed_num_decimals_forced": 0,
"is_thousand_separator_disabled": 0,
"num_decimals": 2,
'title': ['text': "Sample Chart"],
'x_axis': ['steps': 10, labels: ['steps':10, 'visible-steps': 5, 'labels': labels], "colour": "#0067A6", "grid-colour": "#FFCAA8"],
'y_axis': ['min': 0, 'max': yMax, 'steps': calculateYAxisSteps(yMax), "colour": "#0067A6", "grid-colour": "#DEFFA8"],
'bg_colour': '#FFFFFF',
"tooltip": [
"colour": "#5CC0FF", "background": "#FFFFFF", "title": "{font-size: 14px; color: #5C6FFF; font-weight: bold}",
"body": "{font-size: 11px; font-weight: bold; color: #000000;}"
]
]

Friday, January 29, 2010

Grails JQuery plugin 1.4 does not work in WAR mode

Haven't blogged for a while. The arrival of my baby daughter has kept my life quite busy and full of joy, also my sleep deprivation level at a level hasn't been seen since university time.

First day after my paternity leave, back at office upgraded a current Grails project to the fantastic Grails 1.2 and getting ready to release for the iteration. However as soon as I start running the application in WAR mode, I was getting strange exceptions:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JQueryTagLib': Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value

After a bit of digging I realize its caused by the JQuery plugin after I upgraded to 1.4 version. Apparently in JQueryTagLib a typed non-private field "GroovyClassLoader classLoader" was the source of the problem. Because its not private Groovy compiler automatically generates getter and setter for this field, and when Spring tries to inject dependency for this field a class conversion problem happens since the field is typed as strictly GroovyClassLoader, since the native class loader in a WAR environment usually will not be a GroovyClassLoader.

I have contributed my finding to the JQuery plugin project, and the fix is incorporated in the 1.4.1 release, but for whatever reason if your project suffers from the same issue and can not upgrade for the moment the easiest fix would be just simply change the classLoader field to private in JQueryTagLib class under your plugin directory.