Running Multiple Versions of Grails

There may be times when you have to run multiple versions of Grails in your local development environment. It may be because you supporting multiple Grails applications each running different version, or you would like to test your prime Grails app in different version before shipping to customer, or you just grabbed some Grails application from internet( ‘into wild’) and like try out. For whatever reason, in this post i describe one setup that auto detects version of the application and runs it in appropriate Grails version.

Pre-requisite: Unix based machine

General Idea

We set up so that when ‘grails’ command is called, it runs a script. This script will read the version from Grails application(application.properties) you want to run and forwards all of the commands to the appropriate grails version to run.

All of the multiple Grails framework versions are installed in ‘/DevTools/grails’ folder in a format grails-x.x.x.

From the multiple Grails versions, we have chosen one version as default one  and defined env variable GRAILS_HOME that points to it.

Step 1 – Create Script

Create file ‘grails’ in some folder you choose. Make this file executable by running ‘chmod u+x filename’

Next, copy past the following:


GRAILS_CMD=$1
shift

GRAILS_DEFAULT=$GRAILS_HOME

if [ -f application.properties ];then
 export GRAILS_VERSION=`grep app.grails.version application.properties | sed -E 's/.*=(.*)/\1/'`
 export GRAILS_HOME="$DEV_TOOLS/grails/grails-$GRAILS_VERSION"
 echo "application.properties found, using \$GRAILS_HOME of $GRAILS_HOME"
else
 echo "application.properties NOT found, leaving \$GRAILS_HOME as $GRAILS_HOME"
fi

if [ ! -d $GRAILS_HOME ]; then
 if [ ! $GRAILS_HOME = $GRAILS_DEFAULT ] && [ -d $GRAILS_DEFAULT ]; then
        echo "Unable to find $GRAILS_HOME. Switching back to default $GRAILS_DEFAULT"
        export GRAILS_HOME=$GRAILS_DEFAULT
 else
        echo "ERROR: Unable to find \$GRAILS_HOME directory at $GRAILS_HOME"
        exit 1
 fi
fi

echo $GRAILS_HOME/bin/$GRAILS_CMD $*
$GRAILS_HOME/bin/$GRAILS_CMD $*

Make sure to adjust the highlighted line 8 to point to your folder where all of the different Grails versions are located for you.

Step 2 – Setup ‘grails’ Command to Run Script

Update your PATH variable to include the folder containing the script – grails you created in Step 1.

Note: make sure you restart command line terminal to ensure your new updated env variable PATH is loaded

Running Different Versions

Afterwards, when command ‘grails something’ is called, then it goes to your ‘grails’ script. The scripts searches through the application.properties file for the version. Once found, it checks if this version is stored in your machine. If it is not, it runs the default version you have set in ‘GRAILS_HOME’ variable.

There may be times you need to run ‘grails-debug’ command. If that is the case you then change your setup as follows:
1. Rename ‘grails’ script to ‘grails-version’
2. Create new file named ‘grails’ and add the following:

grails-version grails $*

3. Create new file named ‘grails-debug’ and add the following:

grails-version grails-debug $*

Note:make sure you make new scripts executable like step 2

So this will forward ‘grails’ and ‘grails-debug’ commands to versioning script before running either of the commands

Useful Links

Unix Shell Scripting Tutorial

Someone Has Already Registered That SSH key

You may have been using SSH key to login, retrieve code on BitBucket.org for some account. Perhaps, then you wished to do the same for another account but when adding your public ssh key for the another account you got the error – Someone has already registered that SSH key. This post is how to automatically push, pull and connect to any of Repo’s from your machine on any of the accounts hosted by BitBucket.org

We found our solution to this limitation in mercurial extension – mercurial_keyring. In this post we will cover how to install the extensions and then how to configure mercurial to remember credentials for different repos on different accounts in BitBucket.org

About The Extension – mercurial_keyring

Here description from http://pypi.python.org/:

mercurial_keyring is a Mercurial extension used to securely save HTTP and SMTP authentication passwords in password databases (Gnome Keyring, KDE KWallet, OSXKeyChain, specific solutions for Win32 and command line). This extension uses and wraps services of thekeyring library.

The extension prompts for the password on the first pull/push (in case of HTTP) or first email (in case of SMTP), just like it is done by default, but saves the password. On successive runs it checks for the username in .hg/hgrc, then for suitable password in the password database, and uses those credentials (if found).

In case password turns out to be incorrect (either because it was invalid, or because it was changed on the server) or missing it just prompts the user again.

Passwords are identified by the combination of username and remote address, so they can be reused between repositories if they access the same remote repository (or the same SMTP server).

Installing The Extensions – mercurial_keyring

1. Clone The Project

>hg clone https://bitbucket.org/Mekk/mercurial_keyring

2. Configure Extension. To do so update .hgrc config file ‘extensions’ section in your home directory(the global mercurial config) as following:

[extensions]
mercurial_keyring = /path_To_dir_cloned_step_1/mercurial_keyking.py

This will enable the extension – mercurial_keyring for mercurial hg

Configuring For Multiple BitBucket Accounts

In the global mercurial config (.hgrc in home directory) you can config each Repo on different BitBucket accounts as follows:

[auth]
 minnehaha.prefix = https://minnehahalofts@bitbucket.org/minnehahalofts
 minnehaha.username = minnehahalofts
 minnehaha.schemes = http https
 kapasoft.prefix = https://kapasoft@bitbucket.org/kapasoft
 kapasoft.username = kapasoft
 kapasoft.shcemes = http https

In above, we created two aliases – minnehaha and kapasoft each referencing two different BitBucket accounts. The good thing this works for clone  command as well, so now i can quickly clone three different repos on two different BitBucket accounts:

>hg clone https://minnehahalofts@bitbucket.org/minnehahalofts/repo1
http authorization required
realm: Bitbucket.org HTTP
user: minnehahalofts
password:xxxx
>hg clone https://kapasoft@bitbucket.org/kapasoft/repo2
http authorization required
 realm: Bitbucket.org HTTP
 user: kapasoft
 password:xxxx
>hg clone https://kapasoft@bitbucket.org/kapasoft/repo3
http authorization required
 realm: Bitbucket.org HTTP
 user: kapasoft
 password:xxxx

Each time it will prompt for password for the appropriate username. It is only for the first time since we connecting for the first time. Afterwards, the extension save the passwords making it very convenient to push, pull or any other way connect to the Repos

Issues

1. ‘abort: No module named keyring!’

Issue: keyring library missing on your machine. To install, run ‘easy_install keyring’ from command line

 

Useful Links

Grails Database Migration Plugin

Grails Database Migration Plugin is very useful for managing SQL database for your grails application. The most useful aspect of it is that it can generate SQL  scripts from current GORM. In my previous job, we used MyBatis to manage Database, however. With MyBatis we had to create SQL scripts manually and to make it according to GORM was very time consuming, error prone and not efficient process.

In this space, i will cover the installation, setup and everyday use of Grails Database Migration Plugin.

Pre-Condition: SQL Db setup and installed

Install & Setup DataBase Migration Plugin

1. Installation.

To install Grails Database Migration Plugin, run the following command:

grails install-plugin database-migration
-Or-

Add the line ‘runtime “:database-migration:1.1″‘ in the ‘plugin’ code section in grails-app/conf/BuildConfig.groovy just like this:

To verify, open Dependency report (‘grails open dep-report’) and see if there DB migration plugin listed just like this:

2. Generate Initial Script

Next, we are going to generate intial migration script:

grails dbm-generate-changelog changelog.groovy

This will generate ‘changelog.groovy’ containing SQL scripts to create current GORM state and save it in ‘grails-app/migrations’ folder

Note:You may choose to run ‘grails dbm-changelog-sync’ that will record that the changes have already been applied if you don’t wish to dump tables and test this script.

3. Update Datasource

Last, we need to change the app DataSource to inform GORM that it does not need to ‘create’, ‘update’, or do anything with the Database at the application startup since we are going to use DB migration plugin for ‘create’, ‘update’ the app database. So, update variable ‘dbCreate’ in ‘grails-app/conf/DataSource.groovy’ to nothing just like the following:

Using Database Migration Plugin

Test Run

At any given time, to test Database migration plugin and scripts do the following:

1. Drop all tables in the Database.

You can do that manually or utilize Migration plugin by running the following command

grails dbm-rollback-to-date  1900-01-01

2. Roll back the record. ONLY If you drop tables manually you need to update migration record log, so that it appears no migrations scripts have run so far. To do that run the following command:

grails dbm-drop-all

If you have run ‘dbm-rollback-to-date’ as specified above, it would have done this step for you already

3. Run the Scripts and Check Database

To run all of the migration scripts call the following command:

grails dbm-update

This will run any script that is registered in the migration log as hasn’t been run. In our case, we drop all the records, so it will run all migration scripts

Note: At any time, you can check the migration plugin status of what migrations scripts have and have not been run by calling ‘grails dbm-status’. It will display only scripts that haven’t been run

Generating Migrations Scripts

After making changes in GORM all tested then run the following command:

grails dbm-gorm-diff --add filename.groovy

This will generation and register the script as well as include for the filename in the main changelog for you. You are done. Other developer will get your new script and run ‘dbm-update’ to update their database accordingly

Other Useful Migration Commands

1. dbm-clear-checksum.  You can change any Migrations scripts manually but if you do, then don’t forget to run ‘grails dbm-clear-checksum’ afterwards to make the changes valid

2.  dbm-gorm-diff without ‘–add’. If you run only ‘grails dbm-gorm-diff’ without the ‘–add’ tag, it will display what are the current difference between GORM and your database

Run Migration Scripts at Start

Its all good running ‘dbm-update’ every single time you receive new migration script in your workspace , however. You are able to make it automatic at next time your grails application start by adding  the following in the conf/Config.groovy file:

grails.plugin.databasemigration.updateOnStart = true
grails.plugin.databasemigration.updateOnStartFileNames = ["changelog.groovy"]
grails.plugin.databasemigration.changelogLocation = 'grails-app/migrations'

This will detect what changes hasn’t been run from the change log and run appropriate migration scripts all automatically at grails app startup.

Running the migration script also at the time you making changes in GORM (domain classes) q

Issues Encountered

1. ‘Change Set changelog.groovy::[…] (generated) failed.  Error: Error executing SQL ALTER TABLE[…]

We got this error after cloning the project and running the migrations scripts.

It turned out that this error was caused because only on Windows when you generate initial migration script it includes references to specific database name.

To solve it, we manually deleted these references in the initial migration script. Afterwards don’t forget to run ‘dbm-clear-checksum’ to make changes valid

2. ‘Error: Error executing SQL CREATE INDEX `[…]: Incorrect index name’

This error seems to be specific to Database installation,setup or version. Either way, the solution was to manually updated migration script so that this index is created after the foreign key is added

As you can see it is the same index name as marked in above screenshot. So moving the changeSet 5 in front of the changeSet 4 and then updating the numbering(red color) solved the problem for us

Afterwards, don’t forget to run ‘dbm-clear-checksum’ to make the changes valid

3. Grails Migration plugin fails silently.

Most of the time this happens when there is syntax error in one of the migration scripts. I find myself often times deleting a migrations script and then forgetting to update the initial changelog. groovy. At the bottom, the changelog.groovy contains ‘include’ for each migrations script. If you delete some migration script but fail to update (remove the includes) the changelog.groovy, then migration plugin fails silently for ‘update’, ‘status’ and other cmd.

Debugging Grails Database Migration plugin

1. Enable logging. It may help troubleshoot your issue if you enable the Database Migration Plugin by adding following line in Config.groovy:

log4j = {
           ....
           debug 'grails.plugin.databasemigration', 'liquibase'
    }

Useful Sources:

COUNTDOWN TO GRAILS 2.0: DATABASE MIGRATIONS

Working with the Grails Database Migration Plugin

Database Migration Plugin

Configure MySQL with Grails

Oh Grails, you are the Holy Grail!…It makes developers life so easy and so much more pleasant. To configure MySql db with Grails application contains two simple steps:

Pre-Condition: MySql Installed, Database(Schema) created

Step 1 – Configure Connection

In the /grails-app/conf/DataSource.groovy, update you appropriated environment as following example demonstrated for development env:

development {
        dataSource {
            dbCreate = "create-drop"
            driverClassName = "com.mysql.jdbc.Driver"
            url = "jdbc:mysql://localhost/database-name"
            username = "user"
            password = "password"
        }
    } 
...

Step 2 – Instruct load MySql driver

In the /grails-app/conf/BuildConfig.groovy update ‘dependencies’ code block as following:

dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
         runtime 'mysql:mysql-connector-java:5.1.16'
    }
...

Possible Issues

Cannot load JDBC driver class ‘com.mysql.jdbc.Driver’ – If you try to run application and receive the following issue, then you have missed step 2 or specified the incorrect dependency in step 2.