Skip to main content

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

Comments

Popular posts from this blog

Running a Django Application on Windows Server 2012 with IIS

This is a first for me since under normal circumstances we run all our Django applications on Linux with Nginx, but we're in the process of developing an application for another department and due to the requirements around this project, we'll be handing the code off to them to deploy. They don't have any experience with Linux or web servers other than IIS, so I recently took up the challenge of figuring out how to run Django applications on Windows Server 2012 with IIS.

Based on the dated or complete lack of information around this I'm assuming it's not something that's very common in the wild, so I thought I'd share what I came up with in case others need to do this.


This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Assumptions and CaveatsThe operating system is Windows Server 2012 R2, 64-bit. If another variant of the operating system is being used, these instructions may not work properly.All of the soft…

Installing and Configuring NextPVR as a Replacement for Windows Media Center

If you follow me on Google+ you'll know I had a recent rant about Windows Media Center, which after running fine for about a year suddenly decided as of January 29 it was done downloading the program guide and by extension was therefore done recording any TV shows.

I'll spare you more ranting and simply say that none of the suggestions I got (which I appreciate!) worked, and rather than spending more time figuring out why, I decided to try something different.

NextPVR is an awesome free (as in beer, not as in freedom unfortunately ...) PVR application for Windows that with a little bit of tweaking handily replaced Windows Media Center. It can even download guide data, which is apparently something WMC no longer feels like doing.

Background I wound up going down this road in a rather circuitous way. My initial goal for the weekend project was to get Raspbmc running on one of my Raspberry Pis. The latest version of XBMC has PVR functionality so I was anxious to try that out as a …

Fixing DPI Scaling Issues in Skype for Business on Windows 10

My setup for my day job these days is a Surface Pro 4 and either an LG 34UC87M-B or a Dell P2715Q monitor, depending on where I'm working. This is a fantastic setup, but some applications have trouble dealing with the high pixel density and don't scale appropriately.
One case in point is Skype for Business. For some reason it scales correctly as I move between the Surface screen and the external monitor when I use the Dell, but on the LG monitor Skype is either massive on the external monitor, or tiny on the Surface screen.
After a big of digging around I came across a solution that worked for me, which is to change a setting in Skype's manifest file (who knew there was one?). On my machine the file is here: C:\Program Files\Microsoft Office\Office16\LYNC.EXE.MANIFEST
And the setting in question is this:
<dpiAware>True/PM</dpiAware>
Which I changed to this: <dpiAware>False/PM</dpiAware>
Note that you'll probably have to edit the file as administr…