Griffon 2.0.0 and beyond - No Fluff Just Stuff

Griffon 2.0.0 and beyond

Posted by: Andres Almiray on January 16, 2014

After a long pause I'm happy to say this blog is back. What better way to begin a new than by giving a sneak peek of what's coming for Griffon 2.0.0. After the success of the 1.x series the Griffon team went back to the drawing board to redesign the framework with the following goals

  • Make it leaner and slimmer.
  • Target as many platforms as possible (Raspberry Pi anyone?)
  • Be ready for JDK8 (lambdas!)

The first item is quite tricky as it forces the design to be more modular than what it already is, although modularity doesn't mean going all bonkers with OSGi ;-) It's relatively easy to design interconnecting components but then you realize you require something to glue them together. That something turned out to be JSR 330. Griffon already supported basic dependency injection by default (MVC members for example) and advanced dependency injection if an additional plugin such as Spring, Guice or Weld was installed. Starting with version 2.0.0 dependency injection is a big concern; so big that there's no way to run an application without a JSR 330 compliant implementation. The current setup uses Guice just because Guice is the RI for this JSR and the simplest to work with.

Another thing to be taken into account for the first point is the amount of dependencies (and their size) required to run an application. Groovy is a strict requirement for the 1.x series, even if you write an application in Java or any of the other supported JVM languages. Groovy is gr8! But it comes with a 6M cost. Having Groovy in the core also meant bootstraping a CompositeBuilder per MVC group instance even if you didn't use it all. What a waste of memory and resources. The way we figured it out was to move Groovy support to its own plugin. With Griffon 2.x you can truly write a 100% Java application, even the configuration can be written in Java if you really want to! Of course Groovy based applications are the preferred way so don't worry, we're not taking the fun out from Griffon :D

Now that the core is fully implemented in Java we're at a vantage point to reach out from the desktop into the embedded space, targeting the several IoT platforms that have emerged in the latest years. Running Griffon applications on a Raspberry Pi is already a reality; given the right circumstances you may see Griffon applications being deployed to iOS devices (thanks to @robovm) and Android. But don't get too excited about those two platforms just yet, there are a few hurdles that must be sorted out first, such as full JDK7 compatibility and support for reflection calls in said platforms :-/

But wait a minute, how can Griffon target these embedded devices if Swing doesn't run on them? Isn't Griffon tied to Swing? No, not at all! Griffon 1.x supports 6 toolkits (Swing, JavaFX, Pivot, Lanterna, SWT and Qt) where as Griffon 2.x supports the first 4. JavaFX is the key to running visual Java applications in embedded devices, and so Griffon 2.x supports it from the get go.

Lastly, we all know that lambdas are coming to Java with the advent of JDK8 (to be released Q1 2014). While JDK7 is currently the minimum JDK version required to build and run Griffon applications, this doesn't mean the APIs are stuck in the old fashion way. The new codebase takes advantage of SAM types where possible, thus enabling the use of lambda expressions if compiling with JDK8. Btw there's a project called Retrolambda that aims to bridge JDK8 lambdas all the way back to JDK5!

Enough ramblings, I bet you want to see some code, don't you? The following example is taken from the Griffon Guide and is part of the set of sample applications that come bundled with Griffon. The application under review is a simple script evaluator. The script could be of any type however we've constrained it to be Groovy for brevity's sake.

The first file we'll see is the configuration. Seasoned Griffon developers know that when it comes to configuration they have to remember their ABCs, that is Application, Builder and Config. In Griffon 2.x you only have one configuration file: Config. Here's the Groovy version
This file is a combination of Application and Config as found in the 1.x series. So what about Builder? We don't need it anymore. Let's continue with the Model
This artifact looks pretty similar to what we're used to, except for that @ArtifactProviderFor(GriffonModel) annotation; what's up with that? Griffon needs to know some information about the available artifacts that comprises the application. It did so in the past by running an additional step during compilation, as part of the Gant build system it uses. In the 2.x series we chose another path, Griffon now relies on AST transformations (Groovy) and the APT (Java) to generate metadata descriptors at compile time. This feature is used elsewhere for other type of metadata which will see in a moment. Also, this feature has a far reaching conclusion that we'll get to once we try to run the application for the first time (be patient, we'll get there). Next comes the Controller:
Here we have our first taste of JSR 330 goodness. MVC member injection is still performed by Griffon in the old fashioned way, however any other member annotated with @Inject goes through the JSR 330 pipeline. The definition and base implementation of Evaluator follow
So how do we tie things together? Surely there's some kind of magic going on here. Yup, there is. We simply have to define a Module that contains the bindings we want to expose, like so
Module definitions are very close to Guice's but they follow strict JSR 300 compliance, that is, they have no compile dependencies to Guice's API nor its extensions to JSR 330. It's up to the griffon-guice plugin to map these definitions to something Guice can understand in its own terms. Noticed that @ServiceProviderFor(Module) annotation? That's another hint for the AST transform / APT duo to generate compile time metadata. On to the View then
Another interesting change from the 1.x series. View artifacts are full blown classes now (because artifacts must be annotated) however the DSL capabilities are still retained. On the bonus side Views can participate in dependency injection if needed. Rounding up the files that comprise this application we find a single lifecycle handler
Another artifact that has been upgraded from script to full class. Notice that Initialize also participates in dependency injection. Although technically there's no need to write a Launcher class in order to run the application we decided to do so for completeness sake
Launcher classes are great for initializing the enviroment just before Griffon boots up.

Alright, so how do we run this bad boy? I bet you're saying "with the griffon command of course!". And this my friends is where the big change comes in: the griffon command is no more. Nor is griffonw and griffonsh. The build system based on Gant and Ivy has gone the way of the dodo. Crikey! What now? Well, pick your favorite build tool and use it of course! Yes, you read that right. Given the proper build file you may run this application with any of these commands

  • gradle run
  • mvn compile exec:java
  • ant run
Don't believe me? Please review required build files for each tool located at the end of this entry ;-)

Remember the compile time metadata Griffon gathers from your source? Well that's the key to being build tool agnostic as there's no longer the need to tap into a build specific hook in order to compute said data. Also, because there's no specific Griffon buildtime there's no need for custom IDE plugins either. Remember all those problems we had in the past with dependency resolution and missing dependencies on your IDE? Not anymore, as long as your build tool of choice is well supported by your IDE of choice you'll be good to go.

The last file I'd like to show is related to tests, because as everybody knows, tests are important. Griffon test support presents a combination of Grails' @TestFor and GuiceBerry's injection. Lo and behold
Here we see yet another advantage of supporting JSR 330 from the get go, as tests can partially override binding definitions (as shown here) or whole modules if needed be. We still have to decide how integration and functional tests will look like, but rest assured writing them will as easy as everything else in Griffon.

One last thing, the project layout remains exactly the same, as shown by the following snippet

Griffon 2.0.0 has not been finalized yet, the first beta should be out sometime Q1 so please let us know what you think, there's still time to influence the design of the framework for desktop and embedded Java!

Keep on Grooving!

Build files follow

Andres Almiray

About Andres Almiray

Andres is a Java/Groovy developer and a Java Champion with more than 20 years of experience in software design and development. He has been involved in web and desktop application development since the early days of Java. Andres is a true believer in open source and has participated on popular projects like Groovy, Griffon, and DbUnit, as well as starting his own projects (Json-lib, EZMorph, GraphicsBuilder, JideBuilder). Founding member of the Griffon framework and Hackergarten community event. https://ch.linkedin.com/in/aalmiray

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »