Monday, November 25, 2013

Workflow to follow in Grails Plugin creation process

Creating a Grails plugin is quite easy and involves few commands and configuration.
The tricky part is to handle the workflow correctly and understand properly what is going on when you use the available setup.
In any case the fist step is to create the plugin by running the following command:
grails create-plugin <plugin name>
Then there are 3 different ways to install the plugin into a Grails application:
  1. inline plugins
  2. installed from local maven cache
  3. installed from central maven repository
The order is not casual. It reflects the typical fase of the development of a plugin:
  1. when you start coding you will use it as an inline plugin. Using an inline plugin is as simple as putting a new line in main app BuildConfig.groovy file:
    grails.plugin.location."<plugin-name-no-spaces>" = "<path/to/plugin>"
    It's really simple to edit, improve and debug your plugin while you are developing in parallel or not with your main app. Just leave the plugin there and at each reload/restart the code is automatically updated. But the behavior of the plugin is not the same in all three cases: for example, plugin's exclusion is not respected using inline plugin, and also there are compilation steps that are not completely identical.
  2. so when you are ready to test your plugin you can install it in the Maven local cache. This is a feature available from Grails 2.3. Basically you have to run the following command:
    grails package-plugin
    this will create a zip file containing your plugin in one zip. Now you are ready to put it in the local Maven cache:
    grails maven-install
    now you can refer to your plugin as to any other plugin from a maven repo in BuildConfig.groovy, i.e.:
    compile 'plugin-name:0.1-SNAPSHOT'
    Why do I put '-SNAPSHOT' in the name? because Grails doesn't cache snapshot plugins, so there is no risk of installing a stale version of the plugin that is still in development somewhere else like prod env, etc..
  3. Seems that now your plugin is finished, polished and refined. Seems also that it could be useful to someone else? Did you consider to give back something to the wonderful Grails community?
    Then you can submit the plugin for approval to the manager of grails.org portal. It's quite easy and they are great, so just follow some steps:
    • create a user for the portal Grails.org
    • go to this page: Submit a Plugin.
    • fill the form in the page (plugin name, description, repository, ecc)
    • wait for the pull request of changes from one of the manager that will correct most frequent errors or adeguate your plugin to Grails standard, and accept it/improve it.
    • run the following command from the command line:
      grails publish-plugin
      Then just follow the instructions and insert your credentials for grails.org portal.

There are 2 things to consider that I've left behind. There is another way to install a plugin: package it and add the zip file as an inline plugin in your app's BuildConfig.groovy. This is almost like using the local maven cache installation, same compilation, exclusion, etc. but i don't like it because if you are at that point it means that your plugin should start acting like all other plugins, not like an inline plugin.

Please take a look at this wonderful post from Burt Beckwith.
Follow all instructions on how to reorganize the code in a plugin. If you don't do it yourself it will have to be done before the approval, resulting in time and energy waste for everyone.
Also all the information in the created <pluginName>GrailsPlugin.groovy file is important, so fill it properly!

Remember that Github is full of Grails plugins with public code that could serve as an example to you.

This post was created after i submitted my first Grails plugin, so the experience is real and up to date to Grails 2.3.3. Consider to take a look at it: Redis Flexible Cache Plugin.

There are a lot of other arguments and things to say about grails plugin, but i'll create some other posts for that.

Thanks for comments and suggestions. :)

Monday, November 11, 2013

GORM & Lazy Load

There is a tricky thing going on using Domain Classes with collection and Lazy loading. Immagine this situation:

It is quite normal to have the collection represented by a proxy in order to perform lazy loading, in fact in those cases the collection items in reallyDummies are represented in memory with objects similar to this one:

ReallyDummy_$$_javassist_7

at least till first time you access to the collection. If that happen an handler instance of GroovyAwareJavassistLazyInitializer take cares to load the collection from the datasource and associate it to the right object.

The tricky thing is that is not so rare to take decisions accordingly to the class we hare handling, but what happens when you get a proxy instead of the real object?
piece of code like this :

reallyDummies.each{ it ->
  if (obj instanceof BasicDummy){ ... }
}

is almost useless! this because you cannot predict if the object that belongs to a collection o a property explicitly loaded in lazy manner is already in the session and if it will be loaded properly only looking at its base class.

To solve the problem you have two choice:
  1. use the method obj.instanceOf() provided by GormInstanceApi that take care to unproxy the object if needed.
  2. use GrailsHibernateUtil.unwrapIfProxy(obj) if you use only hibernate as datasource.

Remember that GORM Domain Classes are really powerful and originally they were built on top of Hibernate functionality and capabilities.
Form Grails 2.X Hibernate as become a plugin and can be replaced, so GORM can now work with many NoSql datasources!


Thursday, October 31, 2013

Grails & Logging

Logging and Grails

Many developer use logs just to resolve problems and bugs that they stumble in, and many other use logs like there is no tomorrow polluting the code.
Anyone has his own style and there are many guidelines and best practices to follow, so what I want to show in this post is how do I approach logging while I'm coding Grails.

Logging is possible in almost all Grails artifacts using log property, and can be easily turned on and off per Class and packages using log4j configuration in Config.groovy.

But there are some performance issues to keep in mind. One connected to how Java works and one connected to how Groovy works.


Java related one:
if we write log.debug('bravo') everything is super fast.
if we do log.debug("bravo ${preFormattedString}") things becomes to be really slow.
Why? Because before calling any method java must evaluate arguments, and GString evaluation using ${..} notation is quite heavy.
And all this evaluation time will be thrown away if the log for that piece of code is disabled.

Groovy related one:
And here comes Groovy's problem: Groovy power automagically give us the property log.debugEnabled from the method log.isDebugEnabled().
This is syntactic sugar but it's super damn computational heavy: 5/6 time more haeavy!

So it's pointless to optimize your code if you waste so much CPU time for logging that may be not even enabled.

Conclusion:

So use every time this kind of syntax:

if (log.isDebugEnabled()){ 
 log.debug("bravo ${s}") 
}


These are some Gist and relative time consumption to help to understand the problem:

seconds: 0.04017
seconds: 0.03903 seconds: 0.14995 seconds: 0.19269 seconds: 0.03884
That's all. Please comments: all help, corrections and suggestions are welcome.
Credits to: http://burtbeckwith.com/blog/?p=81