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:
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:Button label="Hello" click="ro.hello()"/>
<mx:TextInput text="{ro.hello.lastResult}"/>
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.
@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.
- 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... :)
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.
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).
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="No destination with id 'HelloService' is registered with any service." faultCode="Server.Processing" faultDetail="null"] 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()
-Matthew
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.<init>(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)


