Skip to: Site menu | Main content

A Grails-like Rich Application Platform

Griffon 0.9 Print

Error rendering macro 'toc' : null

Overview

Griffon 0.9 – "Aquila chrysaetos" - is the fifth major release of Griffon.

This release represents a huge leap in behavior and bug fixes, which warranted a bigger jump in version number. There's still room for improvement but the feature set for 1.0 is almost complete. Additional features may be delivered via plugins rather than having them in core.

New Features

Buildtime

Perhaps the biggest improvement at buildtime is the synchronization of the codebase with Grails 1.3.2, which brings the following benefits:

Project Infrastructure

Groovy 1.7.3 Support

Griffon 0.9 comes with the recently released 1.7.3 version of the Groovy language

JUnit 4

Griffon 0.9 now uses JUnit 4 to run tests. JUnit 4 features a richer assertion API and many features like timeouts, ignores, class level before and after methods, hamcrest matchers, assumptions, theories and more.

Pre Griffon 0.9 tests are fully backwards compatible.

Flexible Build Configuration

A new griffon-app/conf/BuildConfig.groovy file is available that allows you to configure different aspects of the Griffon build including output paths and servers used for resolution of plugins:

This file replaces griffon-app/conf/Config.groovy as the source of buildtime configuration. Config.groovy has been promoted to runtime. Configuration set in BuildConfig.groovy (which is per application/plugin) can be merged with global settings if $USER_HOME/.griffon/settings.groovy is available.

Secured Plugin Repositories

You can now configure secure plugin repositories in ~/.griffon/settings.groovy or griffon-app/conf/BuildConfig.groovy for example:

Project Documentation Engine

The same documentation engine that powers the Griffon reference documentation is now available in your projects. Simply create your documentation inside the src/doc/ref and src/doc/guide directories of your project. See the Griffon documentation source for an example.

Build Event Order

The order of invocation of build event handlers now honors the dependency order of the plugin that provides them. For example the CompileStart event handler defined by the lang-bridge plugin will be called before the same event handler provided by the clojure plugin, because the later depends of the former. Previous behavior was to invoke event handlers in alphaetical order of discovery.

Plugins

Multiple PluginRepositories

Griffon now supports the ability to configure multiple plugin repositories by providing a $USER_HOME/.griffon/settings.groovy file or a griffon-app/conf/BuildConfig.groovy file that contains the configured repository details:

The Griffon plugin discovery commands like list-plugin and install-plugin will then automatically work against all configured repositories. To release a plugin to a specific repository you can use the repository argument:

Automatic Transitive Plugin Resolution

Plugins no longer need to be checked into SVN and will automatically be installed via a plugins metadata when the application is first loaded.

In addition, plugin dependencies are now resolved transitively.

Modular Application Development with Plugins

An application can now load plugins from anywhere on the file system, even if they have not been installed. Simply add the location of the (unpacked) plugin to you BuildConfig.groovy file:

This is particularly useful in two cases:

  • You are developing a plugin and want to test it in a real application without packaging and installing it first.
  • You have split an application into a set of plugins and an application, all in the same "super-project" directory.
Licensing and Readmes

A LICENSE.txt file is now mandatory if you intend to release a plugin. Any LICENSE* and README* files located at the basedir of the plugin files will be automatically added to the generated zip file.

Source, Test and Javadoc jars

A source jar will generated for a plugin/addon if any of the following is true:

  • additional mvc artifacts are provided
  • additional sources (src/main) are present
    • you can add more source directories by setting a value for griffon.plugin.pack.additional.sources in griffon-app/conf/BuildConfig.groovy. The value must be a list of directories relative to the plugin's basedir.
  • test sources (src/test) are available

A test jar will contain all compiled classes that may have been generated by test sources from src/test, including test resources from test/resources.

A javadoc jar will be generated from all sources (artifacts, regular, test and additional).

Zip-only plugin releases

If you prefer to use Git/Mercurial/etc. to version control your plugin you can now distribute only the zipped release of the plugin in the central repository and continue to manage the actual sources outside of SVN:

Running Integration Tests on Addons

Previously to Griffon 0.9 running integration tests on a plugin/addon resulted in an error (missing a GriffonApplication instance). However with the availability of a default MockGriffonApplication integration testing is now possible.

Dependencies

Dependency Resolution DSL

Griffon 0.9 features a new DSL for configuring JAR dependencies that can be resolved against Maven repositories:

Built on Apache Ivy, users can now explicitly control how Griffon resolves all of its dependencies without needing to use Maven or Apache Ivy directly.

There is also a new command to easily install dependencies into your local cache for use with the DSL:

Maven Repository Support

Griffon now has full support for publishing plugins to (using the Maven Publisher plugin) and reading plugins from Maven compatible repositories.

You can easily configure additional plugin repositories in BuildConfig.groovy using the Ivy DSL:

The central Griffon repository can also now be easily enabled and disabled by including using the griffonCentral method:

Declarative Plugin Dependencies

Alongside the new Maven repository support you can now declare plugin dependencies using the Ivy DSL:

Which allows you to easily control plugin exclusions:

And the scope of a plugin:

Testing Infrastructure Improvements

Non JUnit providers

The test running mechanics have been completely overhauled, opening the door to all kinds of testing possibilities for Griffon applications. Previously it was very difficult for non JUnit based tests to be deeply integrated into Griffon (e.g griffon-easyb). Expect to see testing plugins taking advantage of this new infrastructure.

Test phase and type targeting

There is now a more sophisticated mechanism for targeting the exact test you wish to run. Previously, it was only possible to target test phases but it is now also possible to target test types .

You target particular test phases and/or types by using the following syntax:

Either side is optional, and it's absence implies all …

It can be used in conjunction with test targeting…

And is additive…

Legacy phase targeting syntax is supported for backwards compatibility

Clean testing

You can can force a clean before testing by passing -clean to test-app:

Echoing System.out and System.err

By default, griffon does not show the output from your tests. You can make it do so by passing -echoOut and/or -echoErr to test-app:

Mocking

griffon.test.mock.MockGriffonApplication is a fully functional GriffonApplication with the advantage that it lets you override the location of all configuration classes: Application, Builder, Config and Events.

Icon

If you choose to change the default UIThreadHandler then you must do it so right after the application has been instantiated and no other operation that requires multi-thread access has been called, otherwise you won't be able to change it's value.

By default, a MockGriffonApplication defines the following:

  • MockApplication - setups a 'mock' MVC group with 3 elements: MockModel, MockView and MockController
  • MockBuilderConfig - defines a single builder entry: griffon.test.mock.MockBuilder
  • MockConfig - defines a single config entry: mocked = true
  • MockEvents - defines an event handler for 'Mock'

The remaining classes have these settings:

  • MockBuilder - a single node named mock that returns a map with any properties that were defined on the node.
  • MockModel - a lone observable property value of type String.
  • MockView - simple script that calls the mock node defined by the builder.
  • MockController - a controller with no actions.

Packaging

META-INF Resources

Both applications and plugins/addons now support defining resources that should be packaged inside their respective jar's META_INF directory. the directory griffon-app/conf/metainf is where all these resources should be placed.

Installer Plugin Integration

Targets coming from the Installer plugin can be used with the package command if the plugin is installed, for example

Results in the same output as running

Additional targets are: rpm, deb, mac, windows, jsmooth

GDSL support

Intellij IDEA 9 comes with Groovy DSL support (Mr. Haki explains it well here). Griffon's builtime jar (griffon-cli) includes a GDSL file for all MVC dynamic methods, threading methods and SwingBuilder nodes. Expect additional GDSL files to become available in plugins as new versions are released.

Gradle Inspired Features

Command target expansion

The gradle command supports camel case expansion of a target, this means you can type

and it will be expanded to 'createPackage' for instance. The Griffon command now sports a similar feature. Creating a new application is as simple as

You'll get a list of options when the expanded script is ambiguous, for example cA resolves to create-app, create-addon and create-archetype, so be sure to write enough characters to let the expansion be resolved unambiguously.

Griffon command wrapper

Another interesting feature of gradle is that it ships with a command wrapper (gradlew) that enables a developer to build a project that requires gradle but without having a preinstalled version of gradle. This means the project is self contained in terms of its build. Griffon 0.9 provides a griffonw command that works in the same way.

This command will download Griffon from a predefined location and run it, thus enabling developers to ship an application in source form to their friends and let their friends build the application without needing to installing Griffon in the typical way.

Application Archetypes

While it's true that artifact templates can be provided by plugins it simply was not possible to configure how an application is created. Application Archetypes fill this gap by providing a hook into the application creation process. Archetypes can do the following:

  • provide new versions of existing templates, like Model, Controller and so forth
  • create new directories and files
  • most importantly perhaps, install a preset of plugins

So, if your company requires all applications to be built following the same template and basic behavior then you can create an archetype that enforces those constraints. Archetypes are simple zip files with an application descriptor and templates. Despite this, Griffon provides a few scripts that let you manage archetypes

  • create-archetype
  • package-archetype
  • install-archetype
  • uninstall-archetype

Archetypes are installed per Griffon location under $USER_HOME/.griffon/<version>/archetypes. Archetypes are registered with an application's metadata when creating an application. You can either manually modify the value of 'app.archetype' to a known archetype name or specify an -archetype=<archetypeName> flag when creating a new artifact.

If no valid archetype is found then the default archetype will be used.

Runtime

Addons

Node and Method Contributions Expanded

It is now possible to contribute nodes, methods and properties to artifacts other than views using the '*' notation, for example:

results in all explicit methods from MyCustomAddon being added to controllers; all methods, props and nodes being added to actions (if actions is configured as an MVC member).

The following additional qualifiers are available too: '*:methods', '*:factories', '*:props'.

Events

Global Event Handlers

The global event handlers defined in griffon-app/conf/Events.groovy are now loaded before any event are fired, including addon events.

Threading

UIThreadHelper Methods on Life-cycle Scripts

You can call all of UIThreadHelper's methods on a life-cycle script using the short notation, the same one available to the application instance and MVC members, i.e. isUIThread(), execSync(), execAsync(), execOutside(), execFuture(). Refer to the Griffon Guide to know more about the threading options provided by UIThreadHelper.

Application Infrastructure

Application Phase

All applications have the same life-cycle phases. You can inspect in which phase the application is currently on by calling the getPhase() method on an application instance. Valid values are defined by the griffon.core.ApplicationPhase enum : INITIALIZE, STARTUP, READY, MAIN and SHUTDOWN.

Application Locale

All applications sport a bound java.util.Locale property whose value is initially the default Locale. You can change this property to let other components be aware of Locale changes as long as they are registered as PropertyChangeListeners on the application instance.

Swing

Shorthand for PropertyChangeListeners

There's a new AST transformation (@griffon.beans.Listener) that enables you to write PropertyChangeListeners without all the boilerplate code. The @Listener annotation can be applied to both properties and classes, and it accepts single closures or a List of closures as value. The following example registers two PropertyChangeListeners, the first using a direct closure definition, the second using a property reference found in the same class

Control Window Display

The WindowManager class is responsible for keeping track of all the windows managed by the application. It also controls how these windows are displayed (via a pair of methods: show, hide). WindowManager relies on an instance of WindowDisplayHandler to actually show or hide a window. The default implementation simple shows and hide windows directly, however you can change this behavior by setting a different implementation of WindowDisplayHandler on the application instance.

The following example shows how you can animate windows using a dropIn effect for show() and a dropOut effect for hide(). This code assumes you have installed the Effects plugin.

In src/main/Dropper.groovy

Notice that the effects are executed outside of the UI thread because we need to wait for them to finish before continuing, otherwise we'll hog the UI thread.

The second step to get this example to work is to inform the application it should use Dropper to display/hide windows. This a task that can be easily achieved by adding an application event handler, for example in griffon-app/conf/Events.groovy

Breaking changes

Removed deprecated classes and methods

  • class: griffon.util.IGriffonApplication
  • class: griffon.applet.GriffonApplet
  • class: griffon.application.SingleFrameApplication
  • method: GriffonApplication.getApplicationProperties
  • method: BaseGriffonApplication.getApplicationProperties
  • method: BaseGriffonApplication.setApplicationProperties
  • method: BaseGriffonApplication.loadApplicationProperties
  • method: GriffonApplicationHelper.runScriptInsideEDT

Moved classes

Buildtime

  • from org.codehaus.griffon.util to griffon.util
    • BuildSettings
    • BuildeSettingsHolder
    • GriffonUtil

      Rationale: Classes under packages griffon.* form part of the supported API and are visible to application developers. Classes under packages org.codehaus.griffon.* are considered internal details, they may change in the future without notice.

Runtime

  • from griffon.applet to griffon.swing
    • SwingApplet
  • from griffon.application to griffon.swing
    • SwingApplication
  • from griffon.util to org.codehaus.griffon.runtime.util
    • AddonHelper
    • CompositeBuilderHelper
    • GriffonApplicationHelper

      Rationale: Classes under griffon.swing prepare Griffon core for a future Swing plugin. Classes under org.codehaus.griffon.runtime.util should be used by the application's runtime only. Also, classes under packages griffon.* form part of the supported API and are visible to application developers. Classes under packages org.codehaus.griffon.* are considered internal details, they may change in the future without notice.
  • Also moved @EventPublisher and EventPublisherASTTransformation to Buildtime/org.codehaus.griffon.ast as having a runtime dependency for this AST transformation make no sense.

Moved methods

  • GriffonApplicationHelper.createJFrameApplication => SwingUtils.createApplicationFrame
  • GriffonNameUtils.getScriptName => GriffonUtil.getScriptName
  • GriffonNameUtils.getNameFromScript => GriffonUtil.getNameFromScript
  • GriffonNameUtils.getPluginName => GriffonUtil.getPluginName

Removed properties

  • app.appFrames is no longer available. Use app.windowManager.windows instead.

Sample Applications

Griffon 0.9 ships with sample applications of varying levels of complexity demonstrating various parts of the framework. In order of complexity they are:

File Viewer

File View is a simple demonstration of creating new MVCGroups on the fly.

Source: git

To run the sample from source, change into the source directory and run griffon run-app from the command prompt.

Font Picker

Font Picker demonstrates form based data binding to adjust the sample rendering of system fonts.

Source: git

To run the sample from source, change into the source directory and run griffon run-app from the command prompt.

Greet

Greet, a full featured Griffon Application, is a Twitter client. It shows Joint Java/Groovy compilation, richer MVCGroup interactions, and network service based data delivery.

Source: git

To run the sample from source, change into the source directory and run griffon run-webstart from the command prompt. Because Greet uses JNLP APIs for browser integration using run-app will prevent web links from working.

SwingPad

SwingPad, a full featured Griffon Application, is a scripting console for rendering Groovy SwingBuilder views.

0.9 Release Notes

com.atlassian.confluence.macro.MacroExecutionException: The JIRA server returned a trusted apps error: USER_UNKNOWN; Unknown User: {0}; ["confluenza"]