Thursday, February 16, 2012

I will defeat you Grails config loader!

by Richard Vowles

As part of the way we do thing, we wanted to use properties files rather than the plain config.groovy - and thats pretty normal - Grails documentation even gives you a mechanism to load in extra config.

Ideally for us, this could be configured outside of Grails - through some Spring mechanism rather than having to modify the Grails config for every app, but its ok - it has worked. Until today. Today I hit the bug in Groovy where the Properties -> ConfigObject via ConfigSlurper started giving weird results. I had these lines

grails.mail.host = localhost
grails.mail.port = 5000

and i was getting

grails.mail.host = localhost
grails.'mail.port' = 5000
grails.mail.port = [:]

which turns out to be a peculiarity of how Groovy loads the file - and there are quite a few bugs around this on the Groovy bug parade - back since 1.6 (and unclosed).

So how to get Grails to load a properties file in my own fashion? Well thats where the fun started. Turns out that Grails hard codes in its scripts the creation of the DefaultGrailsApplication, which in turn has hard coded the ConfigurationHelper. Neither of these were overrideable or extendable without forking Grails 1.3.7. So one of the things we had been doing was using static methods on our class - and in the end, this turned out to be our saviour - that and Groovy's MOP.

As there were lots of parse methods already, I added a methodMissing to detect for a request for a parse with our class and then passed it onto a method of my choosing that would turn the tree into something more resembling common sense.

That seemed to fix it - so if you have the same problem with broken properties loader when using Grails, that approach worked for me.

Wednesday, February 15, 2012

Bad request errors from Sonatype's Nexus during release

by Richard Vowles

So we changed the way we published our artifacts to the repository - going straight to the Nexus, instead of via Apache and having Nexus index them. This meant it was easier from a permissions perspective - making sure the right people could upload artifacts into the right places and Nexus and Apache kept mixing up on-disk file permissions.

That unfortunately turned up a very annoying bug in Nexus - you can't attach 0 length files. Typically for artifacts that could generate a WSDL from code, we'd attach them as a -wsdl classifier artifact into the repository. If there were none, then we would touch the file, so the build-helper plugin could be configured to attach the file, otherwise it would fail.

But the move to Nexus knocked that on the head and we could no longer release web service artifacts - so if you run into a situation when you are releasing artifacts and you get a bad request for no good reason - it may be because you are trying to upload a zero length artifact.

The fix was to remove the zero length file and upgrade to 1.6 of the build helper plugin which has a new capability to skip the attachment if its empty. Our plugin definition now looks something like this:



<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.6</version>
    <executions>
     <execution>
      <id>attach-artifacts</id>
      <phase>package</phase>
      <goals>
       <goal>attach-artifact</goal>
      </goals>
      <configuration>
       <skipAttach>true</skipAttach> <!-- if the file doesn't exist, skip attaching it, added since 1.6 -->
       <artifacts>
        <artifact>
         <file>${project.build.directory}/generated-wsdl.jar</file>
         <type>jar</type>
         <classifier>wsdl</classifier>
        </artifact>
       </artifacts>
      </configuration>
     </execution>
    </executions>
   </plugin>

So I don't forget this

by Richard Vowles

One of the things that that I'm always doing is posting to this blog with the SyntaxHighlighter javascript extension. So to make it easy for myself to remember a bit of code to quickly format the code, I'm posting it here:

'''
code goes <> here
'''.each { c -> print '"><&'.contains(c)?('&#'+(int)c+';'):c }

And it works in the online Groovy console.

Friday, February 10, 2012

Android Tablets

by Richard Vowles

Last year I purchased a Samsung Galaxy Tab 10.1 - I was spending a lot of time browsing the news feeds for stuff for the podcasts, being away from a computer and not being able to make use of valuable time. So I decided to grab a Tablet and see how useful it would be. I was also considering one for use by my wife - given the capabilities of Google Docs Drawing, it was pretty awesome in its ability to do something she was paying for Comic Life on her Mac. I really quite like Android 3.1 and it made moving to my Galaxy Nexus easy and familiar.

It turned out way cheaper than I expected and I have very much enjoyed the experience - unfortunately lately the YouTube has been playing up, but other than that its excellent (seems to be a network issue). The cheap $130 APAD 2 I got was totally useless not because of its resistive screen but because the wifi is utterly lousy, even 1 metre away from the wifi and I can't use it.

The problems I now have with it is that to really use it, I need a keyboard - so ideally I'd replace it with a Transformer Prime with a keyboard - in hindsight I should have waited, but I can always get a keyboard for the Galaxy Tab. The lack of a decent Google Docs client for Android continues to make that application wholly useless unfortunately, so if you are looking for one for that reason, don't bother.