Matt Woodward’s posterous

Matt Woodward’s posterous

Matthew Woodward  //  * CFML, Grails, and Java Developer
* Principal IT Specialist, US Senate
* Open BlueDragon Steering Committee Member
* All-Around Geek

Mar 2 / 11:08pm

March GroovyMag Available -- Includes My "Grails For Switchers" Article

The March edition of GroovyMag is available and includes an article I wrote entitled "Grails for Switchers," which is my account of what I learned while first learning Grails.

If you're at all interested in Groovy or Grails you need to subscribe to GroovyMag. It's a great way to learn more about Groovy and Grails and keep up with what's going on in the Groovy/Grails community.

Filed under  //  Grails   Groovy  

Comments (1)

Feb 20 / 12:21pm

Resolving CSS Issues With Grails UI Plugin

I'm working on another Grails application and am using the fantastic Grails UI plugin for a lot of the UI controls. Grails UI is a really nice Grails-friendly wrapper around the YUI components and includes things like a dialog box, calendar controls, a rich text editor, and a whole lot more. This was my first real foray into using this plugin, so I started with a simple modal dialog box that would show the contact information details for people in a simple list.

The main point of this post is to outline the simple resolution to the CSS issues I was seeing because it took me a while to figure out what was going on, but I thought I'd outline some Grails and Grails UI magic along the way.

First, in order to use the Grails UI plugin you of course have to install it, which is as simple as:

grails install-plugin grails-ui

Next, on any view page on which you wish to use any Grails UI resources, you have to indicate which resources you're going to use on the page. The nice thing about this is it will only load the JavaScript for the specific UI resources you need on each page. In the case of this example I'm only using a dialog box, so I have this line in the head section of my view page:

<gui:resources components="dialog" />

Also in my head section I need to tell Grails I'll be using some AJAX on this page, so I use the javascript tag to load the Prototype library:

<g:javascript library="prototype" />

With Protoype loaded, pulling the contact details to be shown in the dialog box is dead simple using the Grails remoteLink tag:

 <g:remoteLink controller="person" 
               action="showDetail" 
               id="${person.id}" 
               update="personDiv" 
                onComplete="showPersonDialog();">${person}</g:remoteLink>

If you're not familiar with Grails, what this does is tells Grails to make an AJAX call to the person controller, call the action showDetail, and pass the ID of the person object. We'll see what's returned by the AJAX call in a moment. The update attribute of the remoteLink tag tells Grails what DOM object to update with the results of the AJAX call, and the onComplete attribute indicates a JavaScript function to call when the AJAX call is complete.

If all I was doing was updating a DIV on the page I wouldn't need this, but since I need to show the Grails UI dialog box after I pull the contact details, I need a JavaScript function to handle that, so I added this to the head section of the view page:

<script type="text/javascript">
    function showPersonDialog() {
        GRAILSUI.personDialog.show();
    }
</script>

Next, let's check out the showDetail action in my Person controller to see what it's doing when the AJAX call is made:

def showDetail = {
    def personInstance = Person.get(params.id)
    if (!personInstance) {
        def message = "No person found with ID ${params.id}"
         render(view:"personDetail", model: [message : message])
    } else {
        render(view:"personDetail", model: [personInstance : personInstance])
    }
}

Here's the simple view that's rendered in the controller action above:

<g:if test="${message}">
    <p>${message}</p>
</g:if>

<g:if test="${personInstance}">
    <p>
        <strong>${personInstance.firstName} ${personInstance.lastName}</strong><br />
         ${personInstance.email}<br />
        Phone: ${personInstance.phone}<br />
        Cell: ${personInstance.cell}
    </p>
 </g:if>

And finally, here's the code for the Grails UI dialog box and the DIV that is populated with the view above:

<div class="yui-skin-sam">
    <gui:dialog id="personDialog" 
                 width="400px" 
                title="Contact Details" 
                draggable="true" 
                update="personDiv" 
                modal="true">
         <div id="personDiv"></div>
    </gui:dialog>
</div>

This is all pretty straight-forward. What was happening, however, is when the dialog box was shown, there was no CSS being applied to it. The YUI components that are used by the Grails UI plugin have stylesheets associated with them, but when I checked the source code of the rendered page they seemed to be getting included just fine, and as you can see above I wrapped the dialog box in a div with the correct CSS class, which is yui-skin-sam.

At this point it's important to remember that when a Grails page is rendered it uses SiteMesh, which is basically a templating/page decoration framework. As many Grails applications do, I was using a main.gsp layout page, and each individual view page gets woven into this main template.

Therein lies the problem. As I said above this was simple enough in the end but since it took me a while to figure out I thought I'd share. Even though the YUI CSS was being included in the individual view page with the dialog box code on it, for some reason the CSS wasn't getting applied. I decided to experiment and put the yui-skin-sam class in the body tag in my main.gsp layout page, and this solved the problem.

In my case I didn't have any conflicting CSS involved so this solution didn't cause any issues, but if you have other CSS involved and applying a class to the body tag in the main layout page will cause issues, you can add the additional CSS references after the <g:layoutHead /> tag in the main layout page, and this will allow you to override any CSS that came earlier.

With all this in place the Grails UI components are being styled correctly and they're extremely nice additions to any Grails app.

Filed under  //  Grails   Groovy  

Comments (0)

Feb 10 / 9:25am

ThirstyHead: Free Webinar: Getting Started with Groovy, Grails, and MySQL (February 18, 2010)

Wednesday, Feb 10, 2010

Free Webinar: Getting Started with Groovy, Grails, and MySQL (February 18, 2010)

On February 18, 2010, join Scott Davis on a Sun/Oracle sponsored webinar: Getting Started with Groovy, Grails, and MySQL. We'll spend some time working with MySQL from Groovy 1.7 scripts (Sql.eachRow(), Sql.withBatch()). Then we'll switch gears and show you how easy it is to skin a MySQL database with Grails 1.2. Hope to see you there!

If you're interested in Grails this would be a great one to attend. Scott's a great presenter!

Filed under  //  Grails   Groovy  

Comments (0)

Feb 8 / 6:38am

InfoQ: Getting Started with Grails, Second Edition - FREE!

Grails is a Java- and Groovy-based web framework that is built for speed. First-time developers are amazed at how quickly you can get a page-centric MVC web site up and running thanks to the scaffolding and convention over configuration that Grails provides. Advanced web developers are often pleasantly surprised at how easy it is to leverage their existing Spring and Hibernate experience.

"Getting Started with Grails" brings you up to speed on this modern web framework. Companies as varied as LinkedIn, Wired, Tropicana, and Taco Bell are all using Grails. Are you ready to get started as well?

The second edition of "Getting Started with Grails" in now available for free on InfoQ, or you can buy the print version for only $22.95. The first edition was great so I'm really looking forward to reading the update.

Filed under  //  Grails   Groovy  

Comments (1)

Jan 28 / 2:21pm

In Seattle? Into Groovy and Grails? Join the Seattle Groovy/Grails Meetup!

If you're in the Seattle area and interested in Groovy and Grails, make sure and join us at next month's Seattle Groovy/Grails Meetup on February 11. We get together every month at the Elephant & Castle, and it's a casual mix of Groovy, Grails, other technology, and whatever else comes up.

All are welcome so even if you're not using Groovy and Grails yet, come join us and we can all learn from each other. See you there!

Filed under  //  Grails   Groovy   Java   Professional Development   Programming   Seattle  

Comments (0)

Jan 20 / 4:43pm

Componentix blog - Run long batch processing jobs in Grails without memory leaks

In one of our Grails applications we had to run a number of batch jobs. Nothing unusual and Grails supports it quite well with the excellent Quartz plugin.

But when we deployed application in production, we noticed that after running for some time, it consumed a lot of memory and JVM was spending all the time running garbage collection. The reason for it was that our jobs were quite long-running, taking several hours to complete, and Grails wasn’t really designed for such kind of use case.

But "not designed for" doesn't mean it's not possible, of course. Great info about how to clear out some of the things that will eat up memory over time in long-running Grails processes.

Filed under  //  Grails   Groovy  

Comments (0)

Jan 13 / 2:30pm

Multiple Data Sets on Line Charts with Google Chart Plugin for Grails

I'm working on a Grails project and we're using the very slick Google Chart Plugin to handle the charting aspects of the project. If you aren't familiar with the Google Chart API be sure and check it out; even if you aren't using Grails it's a really simple way to add charting to any application. You just call a URL on Google and in return you get a very nice looking chart, and it supports just about any type of chart you can think of. Cool stuff.

One of my tasks today was to get a line chart up and running, and I was having a bit of trouble getting multiple datasets working on a line chart when using two separate Groovy lists. The solution turned out to be simple but since it took a bit of head banging to get there I figured I'd share in case others run into this.

The data I have is simple integers in two Groovy lists (let's call them dataSetA and dataSetB), and in my controller I'm putting the lists in the model for the view so they're already available. Here's the syntax for a simple line chart using the Google Chart Plugin with one data set:

<g:lineChart
    size="[400,300]"
    colors="['00ff00','ff0000']"
    type='lc'
    legend="['Data Set A', 'Data Set B']"
     fill="bg,s,efefef"
    dataType='simple' 
    axes="x,y"
    data="${dataSetA}" />

This worked fine. To add a second data set, you simply separate the two data sets with a comma, so you'd think this would work (or at least I did):

<g:lineChart
     size="[400,300]"
     colors="['00ff00','ff0000']"
     type='lc'
     legend="['Data Set A', 'Data Set B']"
     fill="bg,s,efefef"
     dataType='simple' 
     axes="x,y"
     data="${dataSetA},${dataSetB}" />
 

For some reason the lineChart tag doesn't like that syntax. I'll save you the various things I tried to get the data into the right format so I could pass the lineChart tag a single attribute and just give you the solution. Basically you just create a new list using the two existing lists as its elements:

<% def combinedDataSets = [ dataSetA, dataSetB ] %>

<g:lineChart
     size="[400,300]"
     colors="['00ff00','ff0000']"
     type='lc'
     legend="['Data Set A', 'Data Set B']"
     fill="bg,s,efefef"
     dataType='simple' 
     axes="x,y"
     data="${combinedDataSets}" />
 

As I said, very simple fix but it took me a while to get there. Be nice, I'm still kind of new to Grails. ;-)

Hope that helps someone else who may run into this.

Filed under  //  Google Charts   Grails  

Comments (0)

Jan 8 / 10:40am

Replace Amazon S3 with MongoDB GridFS and Grails

My recent foray into MongoDB got me thinking about using it to serve files. You can do just that with MongoDB's GridFS specification. When a file is stored in GridFS, it is represented by a metadata object and one or many chunks which store a subset of the data. Chunking the files helps with searching but could help replication and sharding presumably. Files in a GridFS store are just like any object in the database. You filter by any of the metadata properties and get chunks on demand or out of order.

Very slick use of MongoDB with Grails.

Filed under  //  Amazon Web Services   Grails   MongoDB  

Comments (0)

Dec 23 / 12:22pm

Grails 1.2 Released

Grails 1.2 final was released today, and there's tons of great new features as well as numerous under-the-hood improvements that make it a very compelling release.

Since I'm relatively new to Grails I'm still wrapping my head around some of the new stuff, but here are some of the more interesting changes in 1.2 from my perspective:

  • Performance Improvements
    Faster is always better of course, so the first thing that caught my eye was the performance improvements in GSP/SiteMesh and the tag library return types (default is now StreamCharBuffer, but tags can return object values too).
  • Environments in Bootstrapper
    Not that this was a showstopper in previous versions of grails, but having to use a kludge or do a quick check of the state of your database to see whether or not you should crank out test data seemed a bit wrong since environment awareness is available elsewhere in Grails apps. Now that it's in the bootstrapper too we can do things the "right way."
  • Per-Method Transactions in Services
    I haven't run into issues with this yet but I could see them coming, so it's nice that you can now declare at the method level whether or not something should be transactional.
  • Named Query Support
    I'm still debating whether or not I think this one is a good idea, but it's certainly interesting. Named query support allows you to define named queries right in your domain classes, and these named queries can then be executed in the same fashion as dynamic finders. The really intriguing thing is that you can run dynamic finders on your named queries, which is tremendously powerful. On the one hand I'm thinking, "Queries in my domain class? That seems wrong." But on the other hand, when they're looked at as "customized dynamic finders," I suppose it's really no more intrusive than the dynamic finders themselves. And frankly given the power you can get out of this feature it's probably worth the small purity of architecture trade-off.
  • Support for SQL Restrictions in Criteria Builder
    Much as I love GORM, sometimes it's simpler to throw some ad-hoc SQL at a problem. This is now supported in the criteria builder which should make lots of the "grab stuff then grab stuff from that stuff" type code disappear (if that made any sense!).
  • GSPs are Pre-Compiled in WAR Deployments
    Small new feature, huge impact in my opinion. On Tomcat instances where we're running a few other apps (especially on 32-bit Windows servers ... don't get me started), we noticed that Grails apps wouldn't start up due to out of memory errors that I strongly suspect were related to this issue. Pre-compiling GSPs reduces the amount of permgen memory space used on deployment.
  • Tomcat is Now the Default Container
    I didn't have a problem with Jetty personally but since we use Tomcat in production it's nice it will be Tomcat in development as well. Note that you can still use Jetty if you like since all the container support is done through plugins. The Tomcat Plugin has a ton of cool additional features like JNDI support in Config.groovy for the embedded Tomcat instance, as well as remote deploy/undeploy scripts. Yes, you can do "grails tomcat deploy" to deploy your app to a remote server. Sweet.
  • Named URL Mappings
    Very handy feature that lets you create URL mappings that may be linked to by name in the link tag/function. For example if you define a URL mapping with the name "fooBar" with attributes of foo and bar, your link tag in a GSP would be <link:fooBar foo="foo" bar="bar">Link to FooBar</link>
  • Improved JSON Builder
    Some nice changes (and an under-the-hood rewrite apparently) here, but note this is a breaking change from previous versions. You can turn on compatibility if you don't want to re-write your code to take advantage of the new simpler syntax.
  • Better Date Parsing
    One of the very few things I've run into in Grails so far that I thought to myself, "this could be simpler," is the way the date picker passes its params to controllers. Now it works like it should have all along.
Much more in this release so be sure and check out the release notes for all the details.

Kudos to everyone involved with this release! Can't wait to upgrade the current app I'm working on and give this all a whirl.

Filed under  //  Grails   Groovy  

Comments (0)

Oct 22 / 12:56pm

Session Notes - Grails Without a Browser

Presenter: Jeff Brown, SpringSource

  • grails typically thought of as a web framework (which it is), but there are significant applications built with grails that have no browser front-end at all
  • interesting work done at LinkedIn in this regard
    • talked about it in public at JavaOne last year
    • primary revenue generating app is a grails app (partner interaction, etc.)
      • this app has no browser front-end to it
      • built a business/service layer all in grails
      • have other applications that sit in front of this that aren't grails
  • lots of stuff in grails doesn't have anything to do with building web apps specifically
    • GORM
    • service layer
    • these make good sense in any application
  • can think of grails as a platform--similar to eclipse platform
    • eclipse IDE is what you think of, but the IDE is really just one app on top of the eclipse platform
    • e.g. substantial parts of grails are being used in griffon for building desktop apps
  • grails 0.4 was the first release that had the plugin system in it
    • interview soon after this release--jeff was asked what was coming up in the following year
    • hope was that they'd see a lot of development in the plugin space
    • turned out that there's a far more active and productive plugin community than they had hoped
    • shows the power of the plugin architecture in grails as well as grails as a platform in general
  • some plugins have nothing to do with an html ui
    • remoting plugins
      • exposes services to remote calls
      • can have the grails side interacting with GORM as per usual, but make these services available to RMI, SOAP, etc.
    • good REST support built right into the framework

Code Demo

  • simple app with Car domain class, CarService
  • services
    • transactional by default
    • instance of service class is automatically added to the spring application context
  • installing xfire SOAP plugin
    • inside a service can declare a property using "expose", e.g. static expose = ['xfire'] in the service
      • this will inspect services that have an expose property declared and make them available via xfire
    • also plugins for exposing as rmi, jms, etc.
  • after fire the app up can browse to http://localhost:8080/context/services to see a list of service WSDLs
    • xfire generated the wsdl automatically
    • can test with something like SOAP UI--UI tool to allow you to exercise web services
  • as you define other operations within the service, the WSDL gets regenerated as needed to expose the new methods
    • with xfire you do need to bounce the app for it to pick up the changes
  • creating a groovy script as a command-line client to the exposed service
    • create a groovyx.net.ws.WSClient, give it the URL to the WSDL, and can then call methods on the web service
    • WSClient is an external project (not core to groovy) so you do need to add it to your classpath
  • note that you don't have access to the Car class when you get back data from the web service
    • you aren't getting back serialized Car objects, it's returning WSClient type of ArrayOfWhatever
      • basically you get back a list of arrays--each array contains the property of the Car object
        • really JAXB elements that contain an xml representation of the car
  • note that by default all of your services are singletons (stateless)
    • if you do happen to have a service that DOES have state, need to worry about thread safety
      • can specify that the bean is scoped in any one of the valid spring scopes
  • controllers are not singletons since they have state--new controllers are created for every request
  • xfire may or may not support (need to check) not exposing specific methods within a service using something like webparam annotations
  • installing jmx plugin
    • can add another entry to the expose property, e.g. static expose = ['xfire', 'jmx']
      • still exposed as SOAP, but also available to jmx
  • creating simple math service
  • can create a griffon client to access the grails service
  • demoing creation of griffon app (results in a swing app)
    • showing two text input fields in swing app, click button to make call to grails service to add the two numbers together
    • actually clicking on the button calls a griffon controller, and the griffon controller makes the web service call to the grails service
      • creating an instance of groovy's WSClient in the griffon controller and calling the same way as from the command line client
  • now creating a RESTful interface to the math service
    • adding a MathController to the grails app with a "product" action to multiply two numbers
    • return from the controller is xml
    • showing calling this in the browser but of course this could be called from anything that can accept xml as the return format
  • now adding another component to the griffon application to do multiplication by calling the REST URL in the grails app
    • plugin for griffon to enable REST support
    • wind up with two buttons in the griffon app, one that makes a soap call, the other making a rest call
  • can use UrlMappings in a grails app to make things more RESTful
  • in controller you can specify the allowed HTTP request types that can be made to the controller by action, e.g. static allowedMethods = [delete:'POST'] would throw a 405 if any request type other than POST is made to the delete action
    • should never do anything destructive in response to a get request
    • if you write controllers from scratch the allowedMethods property is NOT there, and in most cases you'll want to add it
  • in RESTful services, the request will come to the controller since controllers in grails apps are what respond to requests
    • can put logic in services to get it out of your controller, but the REST response since it's based on HTTP request/response needs to be handled in the controller
    • controllers don't have to render a *view* specifically, they just have to provide a response
      • response can be html, xml, json, etc.
  • when you think about grails, building web apps is a huge part of what it's used for, but grails also handles "no browser" apps or multiple UI clients quite well
  • in the end your application is just responding to requests

Q&A

  • anyone working on a plugin so you can write an app that can render either a grails or griffon app?
    • nothing really going on in this specific area, but moving towards compatibility with grails and griffon plugins
    • in many cases you can do a search/replace on a grails plugin to replace "grails" with "griffon" and it'll work in griffon
  • has linkedin experienced any scalability issues?
    • linkedin app get hits really hard and is holding up very well
    • being on the jvm means you have great existing solutions for deployment, scalability, monitoring, etc.
      • can do things in other frameworks (e.g. rails, django) perhaps as quickly as with grails, but that's only one piece of the puzzle
  • what happens when an app and a plugin rely on different versions of the same jars?
    • no good solution for this at this point
    • after grails 1.2 is released, significant effort will be put into the plugin system--need to figure out what role OSGi will play in the future of grails
      • will grails apps and/or plugins turn into OSGi bundles? probably ponder this early next year
  • is GORM usable outside of Grails?
    • yes, and isn't difficult to do now
    • wiring between gorm and the rest of grails is pretty decoupled at this point
    • can use GORM in griffon, for example--drop the GORM jar in and annotate classes, and everything works
      • all the gorm dependencies are in 1 JAR now
    • when using GORM outside of grails you do need to create your own boostrapper or use annotations so GORM knows about your domain model
  • error handling with soap?
    • inside controller action if you get bad data you can render the soap response with the error
    • grails doesn't complicate or simplify any error handling with soap
    • anything you can do to specify timeouts, etc.?
      • rest client for griffon no, wsclient probably does
    • shouldn't assume when something goes wrong in groovy/grails that you always get an exception
      • in many cases grails fails silently, e.g. if you call save() and it fails, it doesn't throw an exception it just returns null
      • can now specify that save() throws an error if save fails
  • what about security with xfire and securing services?
    • can secure access to the webapp at the http level
    • don't know if xfire plugin has specific user/role based access
    • controllers in REST would hook into everything that grails already does--just an http request to the webapp
Filed under  //  Conferences   Grails   Groovy   SpringOne2GX  

Comments (0)