Friday, March 13, 2009

calling dynamic domain finders in Grails

Had the need today for calling a Grails domain class finder method outside of the normal artifact setup. There's a singleton I wanted to write to cache certain hunks of data from the database. It'd be very convenient to have access to those domain classes to save me the pain of writing boilerplate Hibernate config and EJB classes. So, here's what ended up working.

I injected a GrailsApplication reference into my bean and created a closure that I passed to a new Groovy Timer instance. Inside the closure I'm able to invoke the dynamic finders on the domain classes because I can fetch a new instance this way:

def person_class = grailsApplication.getArtefact("Domain","Person")
def person_instance = person_class.newInstance()


That's simple enough, to actually call the finders (in this case "list") the next step was:

def results = person_class.metaClass.invokeStaticMethod(person_instance,'list',null)


Next plans are to create a generic way of exposing the ability to call the dynamic methods so that any Groovy class in the app has has access to them.

Thursday, March 12, 2009

Maven, Grails and Metro -- it works

I was really stoked about the maven-grails plugin when I had some time to start playing with Grails 1.1-SNAPSHOT last week. In fact, Grails has matured quite a bit since I first looked at it a little more than a year go. Almost two years ago I wrote about an integration of NetSuite's WebServices with Ruby's SOAP4r. We've been using this integration for nearly two years and have found ways to improve our original approach. In fact, usage has significantly increased, so much so that scalability is now becoming a concern. Don't get me wrong, SOAP4r has never actually croaked on us. But it makes sense to de-couple this element from the application and make a full-fledged service layer for additional in-house integrations. It's time to port the code to Java.

So, back to Grails and Maven. With over five years of Maven experiences I'm completely sold on its many benefits. I've been watching Grails and hoping that the two would integrate to a point where it's completely usable to manage a Grails project in Maven. That day is here, and it's solid. I created a prototype (love how fast it was) with Axis using Grails 1.1-SNAPSHOT. I was sold. Then, just two days ago, Grails 1.1 was finalized and became GA. Funny thing, as soon as I upgraded my project I could no longer use my prototype because I would receive the dreaded:

java.lang.LinkageError: loader constraints violated when linking javax/xml/namespace/QName

That really made me sad, my prototype was hosed. I didn't want to start sleuthing the class dependency collision. Mike Heath suggested I check out Apache CXF and Sun's Metro, both of which appear to be more "cleanly" designed than Axis. I spent a while trying to get CXF to work, but apparently it has a bunch of jars that need to be excluded since it hosed grails:run-app (No such property: readable for class: org.springframework.core.io.Class).

Finally, I had some success with Metro in Maven and Grails. I regenerated the NetSuite classes via wsimport, and only had to add jaxws-rt and jaxws-tools to my dependencies (this was helpful, https://metro.dev.java.net/guide/Using_JAX_WS_from_Maven.html). For now, I'm up and running and looking forward to more Grails development.