Howard boils the ocean. Use GroovyMarkup! :) New Groovy “use” method added by Sam
Apr 26

Feeling Groovy again

Groovy, Tech Add comments

Ahh, some of the old feelings are coming back. I was on the phone with someone… asking me if I could put together a program that munged some database data and split it out into a file.

I would normally use Perl, but I am feeling Groovy at the moment. So, as I was being explained the problem at hand, I opened up a new file and got to work.

At the end of the explanation, when asked “when could it get done by?”, I was able to say “how about now?”.

import groovy.sql.Sql
import java.io.File

sql = Sql.newInstance(”jdbc:postgresql://dbhost/dbname”, “user”, “pass”, “org.postgresql.Driver”)

new File(”mungeddata.log”).withWriter { writer |
writer.writeLine “Foo, Bar, Baz”

sql.eachRow(”select foo, bar, baz from thetable”) {
writer.writeLine([it.foo, it.bar, it.baz].join(’, ‘));
}
}

All wasn’t perfect though.

I really wanted to reuse a utility class that gets a DB connection by doing the Right Thing (gets a datasource if possible, plays nice with the pool, etc).

So I tried to do:

import groovy.sql.Sql
import mypackage.DBUtil

sql = Sql.newInstance(DBUtil.getConnection())

Unfortunately I got:

groovy.lang.MissingMethodException: No such method: newInstance for class: groovy.sql.Sql with arguments: [org.postgresql.jdbc2.Jdbc2Connection@2a15cd]

UPDATE: James kindly pointed out that I am a moron, and that I just need to use new Sql(Connection). So I changed my code:

//sql = Sql.newInstance(”jdbc:postgresql://dbhost/dbname”, “user”, “pass”, “org.postgresql.Driver”)
sql = new Sql(DBUtil.getConnection())

and it all worked like a charm!

The fact that (in practice) I can easily tie my “scripts” into my Java code is great.

Sometimes you have to write a script that takes in some data, and plugs it into your domain. Often you do that with brute force and shove it into the DB, however it is really nice that now you can:

  1. Munge data in groovy
  2. Package data in a nice way in preparation for …
  3. Accessing your service facade, passing in the nicely packaged data

Great stuff. I do have a couple of frustrations though:

  • Bad error reporting: When things go wrong (compile time) I often get a mega-stacktrace from hell. Really I just want a nice message “couldn’t compile script due to X”. Instead you end up with something like:

    … many lines …
    at groovy.lang.MetaClass.invokeStaticMethod(MetaClass.java:350)
    at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:124)
    at org.codehaus.groovy.runtime.InvokerHelper.invokeMethodInvokerHelper.
    ava:101)
    at dumpmetadata.run(dumpmetadata.groovy:13)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invokeNativeMethodAccessorImpl.
    ava:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invokeDelegatingMethodAcces
    orImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at org.codehaus.groovy.runtime.ReflectionMetaMethod.invoke(ReflectionMetMethod.java:56)
    at groovy.lang.MetaClass.doMethodInvoke(MetaClass.java:846)
    at groovy.lang.MetaClass.invokeMethod(MetaClass.java:268)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    … many lines …

  • Some things just don’t work like I want them to. For example I really wish the following would work:

    println [1, 2].join(’ ‘)

    What do you think you get back? A “sorry old chap, put some parens around will you?”. Nope. java.lang.NullPointerException at groovy.lang.MetaMethod.(MetaMethod.java:84) … add many lines …

    I know I just need to make this println([1, 2].join(’ ‘)), but if you want to make parens optional, do it right :)

Don’t get me wrong…. I know these are growing pains. Hopefully we can take a leaf out of Howards book, and have line-precise errors ;)

2 Responses to “Feeling Groovy again”

  1. James Strachan Says:

    Just a comment on your first error.

    groovy.lang.MissingMethodException: No such method: newInstance for class: groovy.sql.Sql with arguments: [org.postgresql.jdbc2.Jdbc2Connection@2a15cd]

    There is no such method Sql.newInstance(connection). There’s a constructor you could use…

    sql = new Sql(DbUtil.getConnection())

    I don’t know how Groovy could have given any different errors for that one :)

    The last 2 criticisms are totally valid though.

  2. wholesale replica handbags Says:

    thanks for your share.THX

Leave a Reply

Spam is a pain, I am sorry to have to do this to you, but can you answer the question below?

Q: What is the number before 3? (just put in the digit)