Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Sunday, February 25, 2007

Tapestry 5 and Groovy

I was curious just how well T5 and Groovy would work together, so I took an existing application, enabled Groovy for it (using the Eclipse plugin) and added a Groove page to my existing application:

package org.example.hilo.pages;

class Holder
  String firstName;
  String lastName;
  int age;

class Groove {

 def message()
   "Get your Groove on, Baby!"
 def onAction()
  println "onAction invoked"
 def items()
   [ new Holder(firstName: "Howard", lastName:"Lewis Ship", age:40), new Holder(firstName: "Scott", lastName: "Simon", age:42) ]

Guess what? It just worked, no problems. I generated a Grid with the two Holder items, my onAction() method is invocable, and I can retrieve the message. It is just bytecode under the covers.

Alas, without some kind of annotation support, there's no way to mark a field as persistent, so there's tremendous limits on what can be accomplished right now. I've heard rumors that some kind of JDK annotation support is forthcoming; failing that, I've thought about an additional file, read at runtime, that would provide class, method and field annotations. But I'd rather someone else does it.

In addition, Tapestry is reading the compiled .class file; I haven't even thought about trying to get things to work from uncompiled .groovy files and I can imagine there may be some class loader headaches there.

Still, for five minutes effort, it was nice. And I really think I could come to really like the streamlined, sensible syntax ... and for god's sake, first class closures!


Graeme Rocher said...

There is initial annotation support in the current SVN HEAD of Groovy and it will be complete for 1.1

Guillaume said...

Glad you're having fun with Groovy in T5!

As you mentioned, the rumors are right, the next version of Groovy will have support for annotations.

SVN Trunk already provides support for annotations. Some persons have already used it for annotating TestNG tests or EJB3 beans. So it's coming along quite nicely!

Vita Rara said...

I'm working on integrating Groovy with Struts 2. I've taken a few different goes at it. (http://www.vitarara.org/cms/taxonomy/term/68)

The class loader issues are definitely there if you want to use dynamic reloading of classes. I use Spring in my Struts 2 application, and this lead to class loader issues with declarative transactions. One of the Spring developers is looking into that though. He thinks the issues are soluble.

If you use Spring as the factory to create beans for Tapestry it is likely the Spring scripting support, once it is fixed would also work for you. Tune into the threads on the Spring forum, and add your thoughts.

Vita Rara said...

Spring 2.0.3 is out and the scripting support has improved. I've started working with Struts 2 tightly integrated with Groovy. (http://www.vitarara.org/cms/groovyworks)

I have it to the point where I save my Groovy file and hit reload in my browser and the changes are there without a server restart. It makes quick iterations a dream. Tweak, reload, repeat.

Have you made any progress with Tapestry?

Francois said...

(Excuse me for the post in a so old entry)

I didn't test T5 with Groovy, but with Scala : http://www.scala-lang.org/

From the project home page : "Scala is a general purpose programming language [that] smoothly integrates features of object-oriented and functional languages. It is also fully interoperable with Java." (read that last sentence as "you can import Java classes in scala ones, and scala compiler generate .class that run on top of the JVM").

And it just works. Scala already has annotation, so one might expect to use Tapestry full power, but in a full-OO, functionnal language with closure, higher-level functions,type inference and so on.

Quite thrilling !

potter_ru said...

Hello, Howard. Groovy support is broken in 5.0.10. Tapestry during class transformation find in my Page.groovy public field called 'metaClass' and throws exception.