http://seancorfield.github.io for newer blog posts." />

An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

Grails and Flex

February 11, 2008 · 13 Comments

Most of us know by now just how easy it is to write Flex applications backed by ColdFusion. Adobe have done a lot of work to ensure that integration with ColdFusion is seamless. It's very impressive. Browsing through the Grails site, I noticed they have a plugin for Flex so I figured I'd try it out. Following the instructions, I installed the plugin (grails install-plugin flex) which took a fair while to fetch the plugin from the codehaus.org site and build it and install it into my project. Then I created a service class - a regular Groovy class - with just this one additional line:
static expose = [ 'flex-remoting' ]
It had a method, hello(), that returned a string. Then I put my main.mxml file in the web-app directory of my Grails project with these lines inside the mx:Application tag:
<mx:RemoteObject id="ro" destination="helloService"/>
   
<mx:Button label="Hello" click="ro.hello()"/>
<mx:TextInput text="{ro.hello.lastResult}"/>
You don't need to build the project. You don't need to set any paths in FlexBuilder. Just create the MXML file. Then I hit the MXML file in my Grails app: http://localhost:8080/bookstore/main.mxml Much churning ensued as the Flex app was compiled on demand and then up it came with the Hello button. Click. The return value from my HelloService.groovy hello() appeared in the text box. It's a trivial app but it showed just how incredibly seamless the integration is. It uses the Web Tier Flex compiler for on-demand MXML compilation and it automatically manages the destinations for you.

Tags: coldfusion · flex · grails · oss

13 responses so far ↓

  • 1 Joe Rinehart // Feb 12, 2008 at 5:45 AM

    Hrm....sounds kinda cool, except for the whole Web-tier compiler bit. I wonder what it'd take to do a proper services-config.xml for the app and connect it back to the Grails app...it's just looking for an endpoint URL.
  • 2 Tom Chiverton // Feb 12, 2008 at 8:44 AM

    Joe: You could just save the .swf from the browser...
  • 3 Brian LeGros // Feb 12, 2008 at 9:09 AM

    @Joe - The plug-in has the ability to turn off use of the web compiler in its config file, just no implementation for compiling a swf quite yet. I believe the plug-in is creating remoting-config.xml on the fly since it installs Flex in the context of your Grails app; Groovy and Java objects can be registered in pretty much the same way, from what I've seen. If you wanted to integrate Grails as a standardized endpoint you could install the XFire (for SOAP) or REST plugin into your Grails app. I don't think the Flex plug-in creates an AMF endpoint that you can bind a channel to, but I could be wrong.
  • 4 Joe Rinehart // Feb 12, 2008 at 12:17 PM

    @Tom - not quite what I'm after.

    @Brian - That (creating remoting-config.xml) on the fly makes a good deal of sense. Maybe I'm just being difficult, but my workflow for developing a Flex application is usually separate from the development of the services tier (sometimes I'm not even a part of the services tier), so I'd be more after a way to work on the Flex app independently of the entire Grails environment. I guess an approp. builder in Eclipse could spin up Grails to produce the remoting-config.xml then compile the .swf to the filesystem.
  • 5 Sean Corfield // Feb 12, 2008 at 1:04 PM

    @Joe, I suspect the Flex + Grails model of development would be more integrated and iterative, with Flex development and Grails development happening side-by-side. Even so, working in Eclipse and having dummied-up Groovy service classes (in grails-app/services/) with Flex source in my web-app/ directory is working well for me - but I'm not taking any advantage of the Flex debugger right now...
  • 6 Brian LeGros // Feb 12, 2008 at 4:27 PM

    @Joe - I'm going to look into the plugin more. It'd be really great if it exposed that AMF endpoint and then you could connect to it using any Flex app. In Eclipse, Netbeans, and IntelliJ you can spin up the Grails server without much issue (Eclipse has a couple setup steps) so I don't think the idea is far off. I'll let you know if find anything interesting.
  • 7 Maxim Porges // Feb 12, 2008 at 5:37 PM

    Bah! Flex Debugger's for wimps, anyway! All you need is trace().

    - max

    P.S. Yes, I'm joking. I'm just jealous that some of you have Flex Builder and I'm too cheap to buy a license... :)
  • 8 Sean Corfield // Feb 12, 2008 at 6:47 PM

    @Maxim, what do you do for code hinting? I tried the Flex plugin for TextMate (which is, otherwise, great for Ruby, Rails, Groovy, Grails, Subversion etc etc) but it doesn't do code hinting - it just has a ton of keyboard shortcuts / snippets and code coloring.
  • 9 Brian LeGros // Feb 12, 2008 at 7:19 PM

    @Joe/Sean - I just looked at the internals of the Grails/Flex plugin in some more depth and it's using the Flex Remoting jar along with RemoteDestination and RemoteService to create destinations for RemoteObjects at run-time based on which Groovy classes are annotated with &quot;flex-remoting&quot;. I think you could build a Flex app separate from the Grails app if you wanted to, you'd just have to compile your Flex app against the dynamically generated services-config.xml that comes with the Grails app. I'm not 100% about the previous point until I actually do it myself however.

    While digging around, I also found this post by the creator of the plugin: http://marceloverdijk.blogspot.com/2008/01/code-by-convention-with-flex-and-spring.html. WOW! If you're using the latest version of Spring and Java 5+, no reason not to use the @RemoteDestination annotation to reduce the work of editing, managing, and compiling against remoting-config.xml. I think I just got some motivation to use the SpringFactory.
  • 10 Joe Rinehart // Feb 13, 2008 at 4:37 AM

    @Brian,

    Yep, it's very cool stuff, and part of why I've been playing with Java a good deal recently. Combined with persistence annotations, creating a service layer is wicked fast and you never leave domain objects (which is sort of a two-edged sword).
  • 11 Cameron // Nov 18, 2008 at 10:59 AM

    Hi All,

    I still get the RPC exeption when I press the Button...not sure why....I thought you didn't have to configure a destination in the services-config.xml.

    [RPC Fault faultString=&quot;No destination with id 'HelloService' is registered with any service.&quot; faultCode=&quot;Server.Processing&quot; faultDetail=&quot;null&quot;]
       at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()
       at mx.rpc::Responder/fault()
       at mx.rpc::AsyncRequest/fault()
       at NetConnectionMessageResponder/statusHandler()
       at mx.messaging::MessageResponder/status()
  • 12 Matthew Wallace // Dec 28, 2008 at 6:59 AM

    @Maxim You are going to have to use Eclipse or Flex Builder if you want code hinting.

    -Matthew
  • 13 Ajit Kar // Jul 14, 2009 at 10:36 AM

    Hi All,

    I have out of memory error while accessing the main.mxml url. Any help appreciated

    Environment set to development
    [groovyc] Compiling 1 source file to C:\utility\grails1.1.1\mafGui\target\classes
    Running Grails application..
    14/07 18:16:19 INFO Loading configuration file C:\utility\grails1.1.1\mafGui\web-app\WEB-INF\flex\flex-webtier-config.xml
    14/07 18:16:19 INFO Loading configuration file C:\utility\grails1.1.1\mafGui\web-app\WEB-INF\flex\flex-config.xml
    Server running. Browse to http://localhost:8080/mafGui
    14/07 18:17:42 ERROR java.lang.OutOfMemoryError: Java heap space
    at flash.swf.ActionFactory.&lt;init&gt;(ActionFactory.java:170)
    at flash.swf.ActionDecoder.decode(ActionDecoder.java:84)
    at flash.swf.ActionDecoder.decode(ActionDecoder.java:69)
    at flash.swf.TagDecoder.decodeDoInitAction(TagDecoder.java:648)
    at flash.swf.TagDecoder.decodeTag(TagDecoder.java:339)
    at flash.swf.TagDecoder.decodeTags(TagDecoder.java:179)
    at flash.swf.TagDecoder.parse(TagDecoder.java:127)
    at flex2.compiler.media.MovieTranscoder.getDictionary(MovieTranscoder.java:164)
    at flex2.compiler.media.MovieTranscoder.extractDefineTag(MovieTranscoder.java:190)
    at flex2.compiler.media.MovieTranscoder.doTranscode(MovieTranscoder.java:97)
    at flex2.compiler.media.AbstractTranscoder.transcode(AbstractTranscoder.java:138)
    at flex2.compiler.as3.EmbedUtil.transcode(EmbedUtil.java:204)
    at flex2.compiler.as3.EmbedUtil.transcode(EmbedUtil.java:102)
    at flex2.compiler.as3.EmbedEvaluator.generateSource(EmbedEvaluator.java:309)
    at flex2.compiler.as3.EmbedEvaluator.generateSources(EmbedEvaluator.java:374)
    at flex2.compiler.as3.EmbedEvaluator.evaluate(EmbedEvaluator.java:97)
    at macromedia.asc.parser.ClassDefinitionNode.evaluate(Unknown Source)
    at flash.swf.tools.as3.EvaluatorAdapter.evaluate(EvaluatorAdapter.java:338)
    at macromedia.asc.parser.StatementListNode.evaluate(Unknown Source)
    at flash.swf.tools.as3.EvaluatorAdapter.evaluate(EvaluatorAdapter.java:923)
    at flex2.compiler.as3.EmbedEvaluator.evaluate(EmbedEvaluator.java:285)
    at macromedia.asc.parser.ProgramNode.evaluate(Unknown Source)
    at flex2.compiler.as3.EmbedExtension.parse2(EmbedExtension.java:67)
    at flex2.compiler.as3.Compiler.parse2(Compiler.java:386)
    at flex2.compiler.API.parse2(API.java:2381)
    at flex2.compiler.API.parse2(API.java:2339)
    at flex2.compiler.API.batch2(API.java:373)
    at flex2.compiler.API.batch(API.java:1108)
    at flex2.compiler.API.compile(API.java:1318)
    at flex2.compiler.API.compile(API.java:1171)
    at flex.webtier.server.j2ee.IncrementalCompileFilter.fullCompile(IncrementalCompileFilter.java:199)
    at flex.webtier.server.j2ee.IncrementalCompileFilter.compileMxml(IncrementalCompileFilter.java:109)

Leave a Comment

Leave this field empty