Archive for December 19th, 2012

This Week in Grails (2012-50)

Wednesday, December 19th, 2012

The big news of this week was the 2012 Groovy & Grails Exchange in London. Lots of great content this year, and attendance was up 40% from last year. It’s always a great conference thanks to the fine folks at Skills Matter who run the conference and many other events throughout the year. They’re great about getting videos of the talks online quickly and you can check them out at the conference schedule – click through each talk to the full description. There was a lot of Twitter activity – search on the #ggx hashtag. Here are several of the more interesting ones, including several links to presentations and sample code:

In addition, Grails 2.1.2 was released with some fixes for the 2.1.x line (note that the distribution is now ~120MB since it includes source and Javadoc), and Grails 2.2.0 RC4 was released. This will be the final RC release before the 2.2 GA release and it includes Groovy 2.0, so you should definitely check it out and start looking now at upgrading.

The Spring Loaded JVM agent that we use in Grails 2.0+ for code reloading was open-sourced this week.

The folks at Canoo released Open Dolphin which integrates Enterprise applications with Java Desktop applications.

I released a new plugin, the tcpmon plugin. It provides the TCPMon proxy tool which can help with debugging web services and rest APIs.


If you want to keep up with these “This Week in Grails” posts you can access them directly via their category link or in an RSS reader with the feed for just these posts.


Translations of this post:



Plugins

There were 8 new plugins released:

  • dynamic-themes version 0.1.0. Load and render your pages with your own theme (folders with GSP templates and css) dynamically outside the scope of a web request
  • envers version 0.4.4. Integrates with Hibernate Envers
  • extra-runtime-validation version 0.1. Adds validate method to domain objects to perform additional validations at runtime
  • improx version 0.1. Use interactive mode from other process via TCP
  • jasper-response version 1.0. Render JasperReports as PDF or HTML
  • mongodb-compound-index-attributes version 1.1. Add attributes to MongoDB’s compound index
  • raven version 0.5.2. Sentry Client for Grails
  • tcpmon version 0.1. Provides the TCPMon web service monitoring tool

and 33 updated plugins:

  • asynchronous-mail version 0.9. Send email asynchronously by storing them in the database and sending with a Quartz job
  • auto-test version 1.0.2. Monitors the project directory and attempts to run only the subset of tests affected by what changed
  • bootstrap-theme version 1.0.RC3. Provides a basic Platform UI Theme based on Twitter Bootstrap
  • bootstrap-ui version 1.0.RC4. Twitter Bootstrap based UI Set for plugin platform
  • cloud-bees version 0.6.2. Adds scripts to integrate with the CloudBees client API
  • cookie version 0.4. Provides a service and taglib to get, set, and delete cookies
  • cxf version 1.0.8. Expose Grails services as SOAP web services via CXF
  • cxf-client version 1.4.8. Use existing (or new) Apache CXF wsdl2java generated content to invoke SOAP services
  • database-migration version 1.2.2. Official Grails plugin for database migrations
  • dojo version 1.6.1.15. Integrates the Dojo javascript toolkit
  • easygrid version 1.0.0. Provides a convenient and agile way of defining Data Grids
  • facebook-sdk version 0.4.6. Allows your application to use the Facebook Platform and develop Facebook apps on Facebook.com or on web sites (with Facebook Connect)
  • feature-switch version 0.4. Allows turning on and off of features
  • flash-helper version 0.9.4. Simplifies and standardizes the process of adding/reading messages in the flash scope
  • font-awesome-resources version 2.0.4. Integrates the Font Awesome icon set
  • force-response-download version 0.1.4. Forces the browser to open a dialog for downloading content produced within controller actions
  • handlebars version 1.1.0. Server side rendering of Handlebars.js templates
  • handlebars-resources version 0.3.3. Supports using Handlebars.js templates with the Grails Resources Plugin
  • jmx version 0.8. Adds JMX support and provides the ability to expose services and other Spring beans as MBeans
  • localizations version 1.4.4.6. Store i18n strings in a database
  • nerderg-form-tags version 2.1.3. Bringing Readability, Convention, Consistency and CSS to form design
  • page-resources version 0.2.3. Enhances the resources plugin by allowing for creation of ‘page’ resource modules using convention over configuration
  • platform-core version 1.0.RC2. Provides functionality for plugins to use to achieve greater integration with each other and with applications
  • platform-ui version 1.0.RC3. Abstracted UI elements and theming for plugin/application interoperability
  • rabbitmq-tasks version 0.5.4. Run background tasks using RabbitMQ to queue them
  • release version 2.2.0. Publishes Grails plugins either to a public or private repository
  • resources version 1.2.RC3. A resource management and processing framework
  • rest-client-builder version 1.0.3. Provides an alternative REST client implementation based on Spring’s RestTemplate that is not tied to commons-http-client
  • sendgrid version 1.0. Allows the sending of Email via SendGrid’s services
  • simpledb version 0.5. Integrates the AWS SimpleDB datastore into Grails, providing a GORM API onto it
  • spring-batch version 1.0.RC1. Provides the Spring Batch framework and convention based Jobs
  • twitter-bootstrap version 2.2.2. Twitter Bootstrap CSS framework resource files
  • zkui version 0.5.5. Seamlessly integrates ZK with Grails’ infrastructures; uses the Grails’ infrastructures such as GSP, controllers rather than zk’s zul as in ZKGrails plugin

Interesting Tweets

Jobs



User groups and Conferences


Grails plugin dependencies

Wednesday, December 19th, 2012

If you need a jar library in a Grails plugin, the best approach is to add a dependency in BuildConfig.groovy from a Maven repository so you (and your users) only download it once and use it for each project that needs it. This works well as long as the jar is in Maven Central or some other repo, but some smaller projects don’t publish to Maven repos, so sometimes you are stuck with jar files in the lib directory. Using dependency management is convenient, especially since you can override the version in the application later if a newer jar version is released.

The standard syntax is simple, for example

dependencies {
   compile 'com.atomikos:transactions-jms:3.8.0'
}

This is great, but due to the way Maven works this can result in far more than just that one jar file since all of its dependencies and transitive dependencies will also be downloaded and added to the project’s classpath. That’s what you want most of the time, but often I’ve found that there are unneccessary depdendencies, or dependencies that are already provided by Grails or another plugin but with a different version. So I tend to list out all of the dependencies that I actually want to end up with, adding the necessary exclusions to the dependency declarations. For example here are the two that the spring-security-core plugin defines:

compile('org.springframework.security:spring-security-core:3.0.7.RELEASE') {
   excludes 'spring-expression', 'spring-core', 'spring-context', 'spring-tx',
            'spring-aop', 'spring-jdbc', 'spring-web', 'spring-test', 'aspectjrt',
            'aspectjweaver', 'cglib-nodep', 'ehcache', 'commons-collections',
            'hsqldb', 'jsr250-api', 'log4j', 'junit', 'mockito-core', 'jmock-junit4'
}

compile('org.springframework.security:spring-security-web:3.0.7.RELEASE') {
   excludes 'spring-security-core', 'spring-web', 'spring-jdbc', 'spring-test',
            'commons-codec', 'hsqldb', 'servlet-api', 'junit', 'mockito-core', 'jmock-junit4'
}

I could have cheated and just used transitive = false:

compile('org.springframework.security:spring-security-core:3.0.7.RELEASE') {
   transitive = false
}

compile('org.springframework.security:spring-security-web:3.0.7.RELEASE') {
   transitive = false
}

but this is really only appropriate for applications; in plugins it’s better to avoid this so the pom files are correct.


This usually isn’t that hard to do; it’s just a matter of reading pom.xml files and copy/pasting the relevant bits. But it can be tedious and I realized recently that this was an excellent use case for a Groovy script.

If you’ve installed the release plugin (it should be there since it’s added to the plugin’s BuildConfig.groovy by default) then you can run the generate-pom and it will generate target/pom.xml.

The process that I use is iterative. The first step is to use the transitive = false attribute that I said not to use earlier. This will generate a pom.xml with all of the dependencies and transitive dependencies enumerated for you for each of your specified dependencies. Then run this script in a Grails or Groovy console and it will build the proper syntax for each declaration:

String xml = new File('/path/to/pom.xml').text
for (dependency in new XmlSlurper().parseText(xml).dependencies.dependency) {
   String scope = dependency.scope ?: 'compile'
   Set exclusions = []
   for (exclusion in dependency.exclusions.exclusion) {
      String groupId = exclusion.groupId
      String artifactId = exclusion.artifactId

      if ( (groupId == 'xml-apis' && artifactId == 'xml-apis') ||
           (groupId == 'xml-apis' && artifactId == 'xmlParserAPIs') ||
           (groupId == 'xerces' && artifactId == 'xmlParserAPIs') ) {
         continue
      }

      exclusions << "'$artifactId'"
   }

   String combined = dependency.groupId.text() + ':' +
       dependency.artifactId.text() + ':' +
       dependency.version.text()
   if (exclusions) {
      println "\t$scope('$combined') {"
      println "\t\texcludes ${exclusions.sort().join(', ')}"
      println "\t}\n"
   }
   else {
      println "\t$scope '$combined'\n"
   }
}

Replace transitive = false with the output from the script. If this is sufficient then you’re done, but if you’ve excluded a jar file that you will need, then add it as an explicit dependency with transitive = false and run the script again. Repeat the process until all of the important jar files are listed, and all of their dependencies are properly excluded. Keep in mind that you don’t have to list everything, just what you need to get your plugin working. If a user needs another related jar that you excluded, it can always be added to the application’s BuildConfig.groovy.


For a more extensive example, see the db-reverse-engineer plugin’s BuildConfig.groovy. I could have just defined a dependency for the Hibernate Tools jar, but to do it correctly I ended up with six dependency declarations.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.