Friday, January 25, 2013

grails-coffeescript-resources is not working after deploying war in production

There is great Grails plugin that allows to work with CoffeeScript very easily, compiles .coffee files on the fly and does all dirty work.
However, once I tried to deploy my application to test environment, all CoffeeScript files became available in browser as is, without compilation. After some investigation I found out that problem is that it does not supports applications deployed as packed WAR files (with unpackWARs="false" in server.xml), it was pretty easy to fix by modifying plugin script grails-app/resourceMappers/CoffeeScriptResourceMapper.groovy by changing:
 
      File input = grailsApplication.parentContext.getResource(resource.sourceUrl).file

to this

      File input
      try {
        input = grailsApplication.parentContext.getResource(resource.sourceUrl).file
      } catch (FileNotFoundException e) {
        input = new File(original.absolutePath)
      }


and it should work.
One problem is that this change is inside plugin, so you can't do change in your code, and should change plugin itself. I submitted fix with pull request on GitHub, hopefully it will be merged. Until then it is possible to compile your own version from here, or just replace this one line on build server.


Friday, January 18, 2013

Working around grails.serverURL redirect in Grails 2

The most annoying issue with Grails 2 migration is that it requires redirection to grails.serverURL when it is specified. This property is needed if there are absolute links in application (in emails, for example).
First problem that I had with it, was after deploying application to test environment. We deploy production version, so all redirects became redirects to production, this could be solved by externalizing Grails configuration.
Second problem was more severe. We have following setup: load balancer with two nodes behind it. Our deployment script takes first node down, deploys, runs smoke tests, releases first node, takes second node down, deploys, smoke tests, releases.
So basically, production URL is load balancer's entry point, and when smoke tests run on node which is down it is never redirected to tested server (because it is down and it is behind load balancer), so every redirect (after spring security login, for example), breaks tests flow.
After some digging around, I found the best option is to abandon grails.serverURL - which is totally unusable now, and add to email link generation my own parameter from externalized Grails configuration (for each environment). This is sad as createLink with absolute parameter was great function and it didn't required dragging custom parameters.
That is how it is now.
What I would love to see in the future is grails.serverURL is used ONLY in all links generated with absolute:true and nowhere else, but all redirects work as if grails.serverURL not specified at all.

Thursday, January 17, 2013

"Cannot find any VM in Java Home ..." error in Tomcat

During migration from JDK 6 to 7, I found strange issue: Tomcat was working fine when starting via catalina.sh, but was failing when starting via jsvc with just this error:

Cannot find any VM in Java Home /usr/lib/jvm/jdk1.7.0_10/

Jsvc recompilation or any other measure was not helping, but finally I found out that it was running flawless with specific x64 version of JDK instead of i586 version.

Fixing GORM UserType after migration to version 2

Grails allows to define custom UserType to properties like in regular Hibernate, by specifying them next to properties in domain objects, like:


  someproperty type: MyUserType

But after migrating to Grails 2.2, these stopped working and Grails started to treat them as plain objects (enumerations in my particular case). Fortunately, this was easy to fix by defining all custom user types in Config.groovy, like:


grails.gorm.default.mapping = {
  'myproperty-type'(type: my.org.MyUserType, class: my.org.MyEnum)
}

This also defines mapping for all properties of specific type, so no need to do it in every domain class.

Wednesday, January 9, 2013

Importing plugin classes into Grails scripts

Classes from plugin src folder are not available to Grails scripts or plugin scripts itself. They can be compiled and manually loaded, but will be only available for applications or tests launched from script - not to script itself.
However it is easy to work around this issue if it is your plugin or you can rebuild it. It is only needed to compile classes into lib when packing plugin, after that all libs are loaded when running script.
For example this can be done by adding next snippet into _Events.groovy file of the plugin:


eventPackagePluginStart = {
  compile()
  ant.jar ( destfile : 'lib/pluginlibs.jar' , basedir : 'target/classes', includes:"com/myplugin/**")
}