September 10, 2009

Taking Flight: A Year of Griffon

Whenever I fly I like to get the window seat. Sitting on the aisle may get you out quicker, and it may get you quicker access to the overhead bins. But I like the window, for the 15 minutes at the beginning and end of the flight when you must turn of your laptop and take out your earphones. I like to peer out the window and see if I can see the places I came from: my car in the long term parking lot, my house, my office, or the hotel I stayed at. It helps me realize that I've come a long way, but with a lot of help.

I still remember the moment I got serious about my contributions to Griffon. I was sitting at Chinese restaurant for lunch just after JavaOne 2008. While I was reflecting on my SwingBuilder session I did with Andres Almiray I was thinking about where things should go with Swing and groovy and the germ of an idea we had recently named Griffon. I opened my fortune cookie and I can't remember what it said exactly, but it was something along the lines of "They are waiting for you to act." A couple months later I had ported over most of Grails to do a build framework for the JavaOne demo I wrote. I still remember practially dancing down the halls of work the first time I got a full loop working. After some fit and finish time Griffon 0.0 was released, but the array indexing joke was ruined by a crippling mac bug and I had to release 0.0.1 (I've since bought a mac just to rectify that issue).

But as far as I've come with Griffon, I can't forget the help I've received to get things as far as they have come. From the beginning it was a team effort with Andres, James Williams and I. And once it was released community interest was more than I anticipated. Geertjan Wielenga blogged for a solid week or two on a daily basis. Our committer ranks have doubled (although GParallelizer has far outstripped our growth rate). Andres has been amazing with the number of plugins he has written, and James has done more blogging and speaking engagements than I have the time to commit to. But that is what makes a good open source project: a community.

We haven't yet reached cruising altitude, there is still more coming out. Griffon has just release it's 0.2 beta. There are also conferences that will feature Griffon content. Two big ones are SpringOne2GX in New Orleans from October 19-22 (use the code SpringOne2GX75 to save $75 when registering) and StrangeLoop on October 22-23 in St. Louis (sorry, no discount code). So sit back and relax. Beverage service will begin shortly.

February 17, 2009

Groovy Console Bling-Bling

Groovy 1.6 is about to hit the inter-webs, so I thought it was an appropriate time for me to emerge from a twitter induced blogging hiatus. But what to blog about? How about one of the funner items I added to the new release. AST Transformation have changed the way I think of annotations, the bind node in SwingBuilder has brought my GUIs closer to MVC nirvana, and Grapes have been a tasty experiment. But when it comes to plain old gratuitous fun, output visualizations in the Groovy Console will help you see your results in a new light.

GroovyConsoleViz.png

Yes, you probably have seen something like this before, but it's such a neat Idea we had to copy re-implement it.

How does it work? Well, first and formost you have to turn it on. By default it is disabled, so it is less astonishing that way. It's in the menu in View->Visualize Script Results, and we remember what the last seting was when you exit as well. The built in transforms are fairly benign, if the script returns a java.awt.Image, a javax.swing.Icon, or a java.awt.Component that has no parent we display the object instead of the text. Everything else is still text. But that's not really interesting. It is also user extensible! If you have a file ~/.groovy/OutputTransforms.groovy the Groovy Console will insert an empty list named transforms, and you just need to add an appropriate closure into that variable and GroovyConsole will take the results and process those first.

The closure itself is fairly simple. The result of the script is passed in. If you want to transform it you return a non-null transformation. If you don't want to transform it you return null. And the output doesn't need to be a visual component either. You could make all numbers register as percentages:

transforms << { it -> if (it instanceof Number) "${it / 100}%" }

But visual results are much more fun. Here is a simple transform that will make all maps render in tables (it is also the transform that is displayed in this post):

transforms << {it ->
  if (it instanceof Map) {
    def jt = new javax.swing.JTable(
        it.collect{k, v->[k, v?.inspect()] as Object[]} as Object[][], 
        ['Key', 'Value'] as Object[])
    jt.preferredViewportSize = jt.preferredSize
    return new javax.swing.JScrollPane(jt)
  }
}

Don't forget to have fun!

January 2, 2009

Griffon <3's Java

When I first started poking around the Groovy project one of the things I didn't get was the whole MOP thing. Why did every method have to go through the MOP? I thought it was the boat anchor that was going to sink the ship. However, the more I dug into Builders, method injection, closures and delegates, properties, and in general all of the other neat stuff that Groovy does the more I saw that to some extent all of them were enabled by the MOP. Even closures use the MOP, mundane things like trying to figure out where a method call should be dispatched to (the declaring class or some delegate that has been assigned?) uses the MOP. In a sense the MOP is the boat anchor that steadies the language in unpredictable waters.

About the same time I came to my senses about the MOP something wonderful was donated to the Groovy project from the people over at IntelliJ (the IDE that eclipsed my 7 year love affair with NetBeans). They donated a joint Java/Groovy compiler. The Groovy/Java interop story was always very simple. In fact it is so simple an intern could do it. Well, not just any intern. Er... Umm... actually... well... any intern that could fire up two different compilers from the command line could do it. The new joint compiler fixed that, so that any intern who could fire up one compiler could do the interop. The compiler part was really the only hard part because the code looked the same in Groovy and Java, as if you are calling another object of the same language. And at the JVM level the code was the same, following the same naming semantics as Java. However, if any of your interns get a little too excited when you mention a joint compiler and you are thinking of hiring them after the internship, you may want to check with HR to see if there are any policies that they may be concerned about. Some HR departments may be OK with that intern. But be sure to check, you know, for the intern's sake.

So how do those two different threads tie into Griffon? When I first started laying down code for Griffon I intentionally merged the Java and Groovy source trees in the griffon-app. Grails has seperate directory forks in some places for Java and Groovy, of course those decisions were made before the joint compiler was integrated into Groovy. But since I was starting with joint compilation being available, there was every reason to turn it on. And it's turned on everywhere. You could write your controller and models in Java if you wanted to (sounds like a blog post there..) and place the code in the same directories, and it will just magically work.

So when would you want to write code in Java in a Griffon project? First, you would never need to write it to interop with an external java library. Groovy integrates seamlessly with them. In fact, all those snazzy plugins Andres has been chugging out are (for the most part) wrappers for existing Java libraries, packaged into groovy bits for easy use by Griffon. But back to the original question, you would want to write Java (a) if you are more comfortable with it, but it won't take you long to see how easy coding in Groovy is; or (b) if you observe performance issues relating to processor load.

There are two key caveats in the (b) case, (i) observe and (ii) processor load. Why wait until you observe a problem? It has been said that premature optimization the root of all evil. I like to think of it instead in terms of time, it takes you time to optimize code that really isn't causing a problem. When you observe performance problems then you know your work will add value. But before then you are just guessing. Since Griffon aims to improve developer productivity for Swing apps working on unsure optimizations defeats that goal. The other key caveat is processor load. There are many performance issues that really are threading and EDT issues. If you are doing a long calculations you should move it to a SwingWorker or other thread off of the GUI thread. If you are locking on objects... don't. Dropping down to Java won't fix lock contention. Re-think what you are doing and leave data that can be read without locking. And if you are doing database calls in the EDT... let me check with HR before I write up any job offers.

December 10, 2008

Griffon 0.1 Beta Released

After much last minute bug fixing Griffon 0.1 Beta has been released into the wild. You can get the goods at the Griffon Downloads Page. Highlights for this release:

  • Plugins, as prevously discussed.
  • Enhanced Testing Support via the test-app script and plugins such as fest and easyb.
  • Packing via pack200 packing of existing jars for Java 6u10
  • Smarter handling of the auto-sign and auto-pack of jars. Jars are only packed and signed for distribution packaging and the run-webstart and run-applet execution.
  • Some re-working of the MVCGroup APIs. See the FileViewer sample for a subtle example.
  • Any bug with a patch in the JIRA database has been applied, they've all been good so far.

I'de like to thank the other two despots (Andres and James)for their help in development and evangalism and all the early adopters who have given Griffon a look in the 0.0 release. And especially those who submitted patches! That's what OSS is about!

November 25, 2008

Lego Griffon?

No, it's not the next game in the Lego video game series. It's what I've recently checked into the development tree of Griffon: Plug-in support. This will solve a lot of bloat problems with the framework with regards to adding the latest (and some of the not so latest) bells and whistles for your Griffon applications. Don't need JIDE components? Then don't install the jide-builder plugin, even though you really want to. Need an installer for your application? griffon install-plugin installer will get you started. The number of plugins is small now, but that is only because those are the plugins we have been testing the plugin framework with.

So how do the plugins work? Well, mostly like Grails plugins. This is because the plugin framework is deeply inspired by the Grails 1.1 plugin framework (and by deeply inspired I mean many kilobytes of data have passed through my editor's cut and past buffer). Since Grails 1.1 is still very much in development the two codebases aren't totally derivitive, but once 1.1 ships I'll make sure Griffon reflects it's older brother code wise.

Being built off of Grails 1.1 the Griffon plugins may look a bit different. First, they no longer live in the project directory, but in the working cache in your home directory. There are references to the plugins in your application.properties file but that is the extent of data that must fit in your project. Second, because the location of a plugin has changed it wasn't that much of a stretch to allow plugins to be install globally (by adding the -global switch to your griffon install-plugin call), accessible to all projects. This is useful for plugins that are entirely build-time in their purpose, like the fest plugin which adds richer testing support.

Until we release a beta in a week or two you can play with the latest bits from the codehaus bamboo server.

September 29, 2008

Griffon has Flown the Coop!

Griffon durring it's intial development was hosted as a module under the Groovy project. Well, with a public release the time has now come for Griffon to leave the nest and find a new home to roost in.

In addition to it's own hompage the project has moved the user mailing list and added announcement, development, and code commit mailing lists. Code commits come off of our own subversion depot. The bug tracker has already had a couple of JIRAs posted and closed. And just this weekend continuious integration builds have been wired to run on the remote servers at codehaus (Xvfb FTW).

So what does that mean for you? Same deliverables, just coming from a different address.

September 11, 2008

Griffon 0.0.1

Griffon 0.0.1 has been released. This fixes issues related to MacOSX platform customization and cleanup of distribution jars in the clean script.

September 10, 2008

Announcing Griffon 0.0

After over a year of poking and prodding at the various parts of desktop Java the Groovy swing developers are proud to announce the first release of Griffon, a Grails-like tool for Swing development. While not yet industrial strength we felt it was important to put out a release so people can get a feel for what Griffon is and where it will be going. And since all good computer scientists start counting from zero, 0.0 seemed to be the perfect release number.

Griffon Kittens

What are some of the highlights of Griffon?

  • A Grails like build system for desktop apps, including targets to run the application.
  • A directory structure that rewards MVC separation of code.
  • Use of Groovy programming language features to reinforce MVC separation (builders, @Bindable annotation, metaclass method injection, scripts, etc).
  • A view layer based on Groovy's SwingBuilder, allowing for a declarative layout of GUI code.
  • An infrastructure to allow seamless injection of other widget libraries. JIDE and SwingX are supported out of the box.
  • Automatic packaging and signing for WebStart, Applet, and traditional application deployment.

Why call it Grails-like instead of rails-like? The structure of the directories and some of the design idioms do have a heritage back to Ruby on Rails, but Griffon is more inspired by Grails than it was by Rails. And by "inspired" I mean "taking large chunks of Grails code to bootstrap the codebase" (thanks to the ASL 2.0 this is permissible). Not all Grails features have been brought over yet. Plugins and GORM are two notable standouts that we would like to add in future releases.

To download the current release please visit the wiki page at http://groovy.codehaus.org/Download+Griffon and follow the links. There is also an installation guide and a quick start tutorial on the wiki as well.

The distribution also comes with three demo apps developed in Griffon: Greet, a Twitter client; GrailsSnoop, a swing wrapper around the Grails docs; and WidgetKitchenSink, a demo app of various widgets supported by Griffon. These applications live in the samples directory and can be run directly by "griffon run-app".

There is clearly much more that can be done, and this is just the beginning. Future releases hope to bring in client side GORM, pack200 support, plugin support, and more GUI libraries. Like most open source projects external contributions and participation are always welcome. For questions and comments there is a griffon-user@groovy.codehaus.org mailing list set up.

August 29, 2008

Griffon and Greet: Starting to get Groovy

Things on Griffon and Greet have been chugging along. Just a soon as Groovy 1.6 Beta 2 ships I'll likely be ready for a 0.0 release, and such. (Remember, we are all computer scientists, and we start counting from zero). In the meantime here is an applet of the main demo for Griffon. This works best with the 6u10 release, and it may not work in your RSS readers either.

This is using Josh Marinacci's Applet Poster Frames, so click on the image below to get started.

If you would like to look at the code (1) SVN sync http://svn.codehaus.org/groovy/trunk/groovy/modules/griffon/ and (2) Dude, ur a hax0rz now!!!!oneelevenone!. Seriosly though, a proper tutorial will accompany the 0.0 release in a few weeks.

Enjoy!

June 10, 2008

More than I wanted to know about groovy.lang.Closure

Mind you, I'm not going to tell you everything there is to know about Groovy's implementation of Closures. The principal reason being I don't know that much. For the most part I really like Groovy's closures, because they just magically work and I don't have to worry about adding final to externally referenced variables under threat of compilation error. But there comes a time when making a feature work like magic that you just have to know the details of the magical incantation.

It started out innocently enough, with Andres Almiray coming to me at JavaOne 2008 and suggesting the next great idea for the SwingBuilder: make the bind node work with closures. Well, at least well behaved closures. Because sometimes terseness adds more to readability and usability than rigor does. Consider these two lines, which would you prefer to code and read?

label(text: bind(source:model, sourceProperty:'value'))
label(text: bind {model.value})

Certainly, it should be the second line. Immediately my head started to churn, and my first impression was 'is there some way we can make AST Transformations do this?' Because (a) the first beta of 1.6 had just gone out with AST Transformations making it's debut and (b) this seemed like a compile time problem. But quickly things came screeching to a halt. You see the problem is that in Groovy all method calls and property references are dynamic. Meaning that they go through the Meta-Object Protocol (MOP) to dispatch the call or resolve the value of the property. And the actual methods used to resolve these values can be completely altered at runtime (with the right permissions). This presents a problem with compile time transformations: how do you safely do a transformation on a symbol that may not mean what you think it means at compile time? The short answer is you don't. (The longer answer is deserving of another blog post).

So how can I bind to a somewhat arbitrary closure, one who's meaning isn't fully resolved until runtime? The answer is to use the same mechanisms the closure uses at runtime to resolve it's values, but make a mockery of it instead. Err.. I mean.. use the mock object pattern. This is actually where I started to learn more about the incantations of closures than I intended.

In Groovy, each closure creates a separate type, whose name is a mechanical mangling of the owning type: <Class Name>$_run(_closure<number>)+ and each of these types extends groovy.lang.Closure. However, a closure needs to get some access to the methods and properties of the scope in which it was declared and/or in which it is executed. To this end, it has an owner field, which is always set to the instance it was created in, and a delegate field which can be set to any old object. The resolveStrategy property on the closure is then used to determine which of the fields to use and the order to address them in to resolve methods and properties not directly know to the closure. This was simple enough, since I already exploit that knowledge to get any of the builders to work their magic in the first place. However, once I got the simple case working, the real magic of closures made itself manifest: lexically scoped variables. Consider this script:

String bar = "long"
def closure = { [bar.length(), baz.length()] }
bar = "longer than long"
closure.delegate = [bar:"short", baz:"short"]
println closure()

What will the result be? Wait for it.... is it [4, 5], [5, 5], or [16, 5]? The correct answer is, of course the last one. But how can that be? In Java with an inner class I would be forced to declare bar final, and remove the third line since I cannot alter it, so in Java the first answer would almost always be true. But to get the second answer instead of the third one I would have to remove the typedeclaration for bar, and this is the point where I started to see some of the deep magic at work. Whether or not bar is defined as a free variable or a lexically scoped variable is an essential distinction for a Closure. Properties are not lexically scoped variables, and lexically scoped variables are not pushed through the MOP for resolution like properties are. Lexically scoped variables basically have a static meaning, even when used in a closure that may leave scope. (note: the variables themeselves are not subject to the MOP, but the methods or properties on said variable, those are subject to being MOPed up).

So when Groovy compiles a closure and generates bytecodecode it looks over the lexically scoped variables it can see, and compares it against the symbols that the closure is using. When it encounters a variable that is used by the closure it does two things, first it adds to the closure an argument in the constructor, a field, and a getter method to access the variable within the class. Java does this for Inner classes so it is not too shocking. But the second thing it does, which is simple but powerful, is it wraps all access to the variable in the enclosing scope and in the closure inside of a groovy.lang.Reference object. The code looks like it may be accessing an Object on the stack, but the compiler alters those calls for you so you are actually accessing the reference object and using get and set to read and write to the variable. This allows the variable to, in essence, outlive the stack frame it was created in and for other closures to act on the variable in a manner that can be shared across other closures. Consider this slight alteration...

String bar = "long"
def closure = { [bar.length(), baz.length()] }
bar = "longer than long"
def change = {bar = "Doh" }
change()
closure.delegate = [bar:"short", baz:"short"]
println closure() // [3,4]

Providing an alternate value in the delegate still has no effect, but altering it's value inside another closure does affect it. Knowing this I could now create a separate instance of the Closure and fully mock it up against both lexically scoped variables and free variables in an equivalent fashion. The simple act of adding a type to a previously unbound variable will now no longer break things in strange and mysterious ways. Making things work like magic made me learn more than I ever expected to know about how Groovy implements Closures.