For years, I’ve been using a very simple but very effective technique to introduce myself in job interviews, and I’ve always got some excellent feedback about it. I’m not talking about the content here, but the format. It can always be a bit tricky to introduce yourself without diving too much into irrelevant details, or losing yourself along the way, or boring the interviewer to death. To avoid all that, I’ve learnt this technique at Axen, but since Axen doesn’t exist anymore per se, I might as well share it with you guys, because it’s always a shame to miss a good recruitment because the candidate wasn’t clear enough during his/her interview. So here you go…
I’ve been using Grails extensively for a year or so, and I love it, I really do. I even wrote a couple of plugins for it, including one for integrating Grails with Apple Push Notification Service. But since I’m always looking for productive ways to develop, I always thought that Grails and Flex were the best combination ever… until I hit the brick wall!
There’s a Grails Flex plugin, but it has 3 major issues:
- The Flex plugin has not been maintained for years, and it uses the old-fashioned way of integrating BlazeDS into Spring instead of the more modern, robust and easy to configure Spring BlazeDS integration library
- It doesn’t deal at all with authentication and authorization which is for me a critical issue in any remoting setup. And the Flex plugin doesn’t really offer a solution to that.
- The Flex plugin integrates BlazeDS3 and suggests you should mix your Flex sources with Grails project, which doesn’t make it easy to work on the Flex part using Flash Builder and its great data connectivity wizards.
Those are the 3 reasons why I’ve been working on the Grails BlazeDS plugin which works great with Grails up to version 1.2.x. Unfortunately I’m tackling some challenges with Grails 1.3. And even with Grails 1.2.x, there are still some limitations with Flash Builder, mainly due to the fact that
- Flash Builder requires a standard WAR layout, which “grails run-app” doesn’t create
- Flash Builder doesn’t like artifacts that Groovy adds to classes at compile time, so it’s not able to generate client-side stubs
So from a Grails/Flex integration standpoint, we end up being stuck between an old solution that is working but incomplete and not integrated in tools, and a more modern solution that does not work anymore and forces us to use some workarounds.
All the community needs to make this work is a little coordinated help from Adobe and SpringSource so that we can have:
- a BlazeDS 4 + Spring BlazeDS 1.5 + Spring Security 3 integration plugin for Grails 1.3 and above
- a data connectivity wizard that does not require a standard WAR layout and is capable of generating client stubs based on Groovy classes.
I’ve left a couple of messages on Grails mailing lists, Adobe forums and SpringSource forums, but so far, all my calls for help have remained unanswered. So if anyone is willing to help or support this ongoing initiative, it’ll be greatly appreciated. Just leave a comment if you need such a better Grails /Flex integration and maybe it will trigger a red light somewhere at Adobe and/or SpringSource. And if someone from Adobe or SpringSource is reading this, please help!
I feel like I’m just waking up from an awful nightmare. Actually “waking up” might not be the right expression since I haven’t slept in 30 hours but you get my point. Let me tell you my little story.
2 years ago, when the iPhone 3G came out in Belgium, I had been waiting for an iPhone for so long that I simply couldn’t help being there on the first day. So when Mobistar launched a small marketing stunt by starting selling the iPhone at midnight, I decided to wait in line. And I did. From 4pm the day before until I received the iPhone 3G number 50 for all Belgium at 2am in the morning. The experience was painful at the end, especially because I had totally forgotten to bring a chair. But overall it was very rewarding and I was very positively surprised by the way Mobistar had organized the whole thing.
Last year, I completely missed the iPhone 3GS launch so I had a few hard weeks trying to find one.
That’s why this year, for the iPhone 4, I decided to go wait in line in the biggest Apple Store in France, in Paris, at Carrousel du Louvre. Oh my! What a disappointment! Just to sum it up so you can imagine what mood I’m in: one sleepless night, more than 300 euros in train and parking tickets, 15 hours in line including 8 hours standing, hence 2 feet hurting like hell… and not one single iPhone 4.
I was there at 9pm yesterday. Everything started nice. I was only the tenth in line. I had just bought myself one of these very comfortable and robust camping chairs. I had my iPad and some WiFi. I enjoyed it. And then things progressively but rapidly went very wrong. In front of me, there was a bunch of Russian guys who started drinking uncontrollably, and since there was simply no organization whatsoever, nothing prevented their Russian friends to join them late in the night, without any respect for the guys who had been waiting here for long hours. Then the rumor started to spread that the Carrousel galleries would open at 4am exceptionally. So when 2 security guards approached the door, no barrier, no Apple guy, nothing or no one prevented the line to turn into a big compact crowd where last come became first served. And we waited there for nothing to happen, standing, from 4am to around 6am. Eventually the security guards ended up opening the door. In fact not THE door we were all anxiously waiting in front of. No! Too easy! Another door on the side of the gallery, resulting in a chaotic and unbelievable crowd movement that finished up the last bits of line order there was.
So it was around 6am when other security guards started to appear, and those guys obviously had no clue how to handle a crowd, let alone an international one (have you ever tried to reason with a drunk Russian guy?). They just yelled at us, ordered us to move backwards and then forwards again, a couple of times, and at 7 am we had yet another differently ordered “line”, standing. But at least the security guards managed to maintain some sort of discipline by filtering who could enter the queue right in the middle for some reason. An Estonian guy behind me successively introduced his wife and his girlfriend. Of course, once they were in the line, they couldn’t care less about the dude.
And then around 7:30am, guards started disappearing again, obviously called to greater ventures down in the galleries, and chaos came back until they started letting people in, in small groups, a little before 8am. We thought “that’s great, they’re letting people in at the rate the Apple Store can process their purchases.” There were around 150 people in front of me (remember, I was 10th in line at the beginning), so I figured I might be able to execute my plan and catch my train back at 9:25am. How foolish of me!
There was another line inside the gallery! So the small groups who were let in all started running in order to win a few precious ranks (remember, I had not slept in 24 hours at that time, very practical to run like crazy!). But wait, it gets worse, there was not one line inside the gallery. There were 2!!! One for us fools who hadn’t reserved our precious little one. And one for those who reserved it online and just came to pick it up. Wait! What? Pick it up! Why aren’t those guys just waiting at home for the postman to come by and bring them the precious little one in the comfort of their home? What the heck is this pick-up thing? And soon we realized that they were letting people inside the Apple Store in a proportion of 8-9 reservations for 1-2 people without reservation. Wait! What?! What the hell is the rationale about that? At most, reservation is supposed to guarantee that you will have one, not that you will have one before everyone else!
But wait, it gets funny too. Remember those proportions? I said nothing about the rate. According to our estimation, it took somewhere around 15 to 30 f***ing minutes for a blue-shirt-guy to process one customer. 30 minutes! So guess what happened? The line of reservations grew longer and longer with fake reservations, the line of non-reservations turned into yet another big chaotic pack, security guards kept yelling at us, ordering us to move backwards. Yes, backwards! All of that while the Apple store seemed to be able to process somewhere around 20 persons per hour. So the pack I was in moved 10 meters in 4 hours, I kept seeing people without reservations suddenly changing lines magically and getting out with 4 iphones at once. And yes, at 12pm, I gave up!
I decided my body had taken enough stress. I stepped back and realized that an iPhone was not worth that! Especially not a black one anyway! So I just left the queue, went back to the train station, bought another train ticket at an indecent price hoping that I would get back home as soon as possible to spit out this bad nightmare and forget everything about it.
And here we are. It’s 4pm. I don’t have any iPhone 4, I’m frustrated and I’m pissed. I’m so pissed at Apple right now. If someone from Apple is reading this, read it carefully! Not only am I a basic fanboy of yours, but I’m also an iPhone/iPad developer and my 2 modest apps on the App Store participate in the great ecosystem that allows you to sell all those magical devices. And even without all of that, I really expected from you a buying experience at least equal to the one I had with the little Mobistar 2 years ago. And in the end, no organization whatsoever, no one from Apple to handle the logistics in the queue late in the afternoon, no one to give clear and consistent instructions to those security guards, no communication about why things were so slow. And slow they were! And chaotic too. Several people fainted in the line, a lot of people cheated, everyone was pissed off to a point you can’t even imagine. Now let me tell you this and read my lips: if that’s the only possible outcome of your corporate ego going through the roof, if all you can do is treat your most loyal customers like this (check my recent purchase record), then I SUDDENLY FEEL LIKE BUYING AN ANDROID PHONE (and developing for it!). But you don’t care, right? Because so many people are buying it anyway…
I’m exhausted. I’m starving. I’m frustrated. And all I can do right now is spit it out on my blog and laugh at myself for being such an overly optimistic fanboy consumerist. And all I want to do is forget about this day. Apple, you just created the new worst day of my life so far as I can remember. And I don’t thank you for that.
Still one session to attend about closures in Objective-C, and I’ll call it a week. A little bit of shopping this afternoon in order to spend my last dollars and I’ll be ready for take-off tomorrow afternoon. So it’s time for a little summary of this week.
Overall, it was my first WWDC and I’m very glad I did it, but I probably won’t do it again. San Francisco is definitely a very nice city, and seeing Steve in live, even from very far away in the audience was an interesting experience. I also learnt a few very interesting things and psychologically a conference like this always has the same side-effect on me: first I’m depressed and humbled by all the ambient intelligence, but then it motivates me a lot to move forward, learn and do something about it. So it has definitely been a very positive experience.
Now was it worth the budget I put in it? Continue reading WWDC 2010 Review
In the previous episode, we built a simple Grails backend for the todolist application. In this installment, we will create a simple Flex 4 front-end for this backend.
The following assumes that you have already installed Flash Builder 4 (formerly known as Flex Builder), either in standalone mode or as an Eclipse plug-in.
A couple of years ago, I published an article on this blog entitled “Flex, Spring and BlazeDS: the full stack!” and this article became very popular. Actually it broke my daily visits record. Today I’m gonna try to break this record again.
In the last couple of years, I’ve worked a lot with Flex and Spring. But in my eternal quest for productivity and user experience, I discovered Grails. Based on the same ideas as Ruby on Rails or Django, it combines a dynamic language – Groovy – with the power of “convention over configuration” to make it possible to create web applications in no time, thus allowing you to spend more time on your user experience.
Of course it’s not the only thing that has changed since then. Flex 4 is now finally out in the open. BlazeDS 4 too. And Flash Builder is finally productive enough for me to use it… in combination with IntelliJ IDEA of course.
All those evolutions in my toolset needed to be integrated, so I ended up building a Grails plugin to do just that: Grails BlazeDS plugin. And since this plugin could not be officially released without a proper demonstration, here we are.
I prepared this tutorial for a BeJUG talk I gave last week. So I want to thank Stephan Janssen and the BeJUG for inviting me… and for staying with me without throwing vegetables at me, given all the failures I had during the live coding session. For those of you who were there: I clearly identified PermGen space as the guilty part responsible for all these blank screens. In fact, since Grails migrated from Jetty to Tomcat as their runtime server, default java memory settings are not enough anymore, so I always configure my projects for that, but of course, in live, I forgot…
Anyway. I’m going to publish this tutorial in three episodes, each one of them being accompanied by its very own screencast on Vimeo (damn Youtube and their 10-minute limit!). But I’ll also publish the tutorial transcript right here for those who want to go faster.
Important note: this tutorial covers the following set of technologies in the specified versions:
- Grails 1.2.2
- Grails Spring Security plugin 0.5.3
- Grails BlazeDS plugin 1.0
- Flex 4
- BlazeDS 4
- IntelliJ IDEA 9.0.2
- Flash Builder 4
- Spring BlazeDS Integration 1.0.3
- Spring Security 2.0.4
- Spring 3.0.0
In particular, it seems that Grails 1.3 that was just released a couple of days ago breaks Grails BlazeDS plugin. I’ll update both my plugin and this tutorial when I can make them all work together again.
Just a quick note about past and future talks. Yesterday evening, I gave a presentation at Brussels’ Café Numérique to set a few facts straight about Flash and try to stop th FUD madness. It was very funny trolling in live. Excellent atmosphere. If you’re a Belgian geek (or you don’t want to be afraid of technologies anymore) that’s the place to be every Wednesday.
In my humble opinion, the main reason why the debate around Flash versus HTML5 (and Adobe versus Apple) has gone haywire during the past few weeks is that everyone is lying about their true motives (like in any apparently inextricable conflict):
- Apple doesn’t want Flash on its closed devices like the iPhone, iPod Touch and iPhone because Flash would be an alternate content channel that would hinder Apple’s very lucrative iTunes business. And of course they won’t admit it because it would mean that they put business strategy before innovation.
- Adobe has some technical issues with Flash because the codebase is very old and costs a lot to maintain. And they won’t admit it because it would make Flash look weak and unreliable on the long term.
- Flash developers (including yours truly) have invested a lot of time, money and effort in tools, training and experience with the Flash platform, and are not so enthusiastic about throwing all of that down the garbage for yet another fashion tech. But of course we won’t admit that because we’re afraid to look like dinosaurs who refuse to evolve.
And since everybody uses pretexts, everyone will use every contradiction and approximation possible to maintain their cover. Like I said, wars work the same way: ideology hides facts. It motivates your troops to fight the other side until they’re dead, because the big guys, the ones who know about the real reasons simply can’t find a peaceful solution that would allow everyone to win.
It reminds me of a European civil servant who asked me this simple question once when I started a mission for the European Parliament: “Why do you think the European Union was created?” Naively I answered “so that one day we can be on equal foot with the United States.” “Wrong!” he said. “That’s not what Shuman and its friends had in mind. After World War II, they realized that the true source of the conflict between France and Germany, and by extension between their respective allies, was the repartition of natural resources in general, and most notably at this time, coal. But it’s hard to get people to fight for that kind of cause, so powers had to disguise it with ideology so that people would feel invested and do terrible things in the name of it. And they understood that if they didn’t cure the real sickness instead of fighting the symptoms like they had done after World War I, they could not prevent it from happening again. That’s the real reason why CECA was created, and then CEE, then EU. It was not a matter of power, it was a matter of peace.”
And that answer struck me because the same pattern repeats itself over and over again in a lot of contexts. Behind decades of war between Israel and Palestine, there’s a fight for water. Behind the war in Irak, there was a fight for gas. Behind the war for the future of web technologies, there’s a fight for customers. And the conflict is even more violent as it happens on 2 different levels: company-wise between Apple and Adobe, and community-wise between Flash developers and HTML developers.
The good news is that there’s a way for everyone to win peacefully once we reveal the real issues. There are enough customers for everyone. It’s not a zero-sum fight. The other side doesn’t have to lose so that we can win. The question is: will we be strong enough to reject the ideology and find a common ground at the community-level? Or will we let the big guys at Adobe and Apple hide behind ideology and use us as cannon fodder.
One of the main goals I’ve been pursuing for a few months is the integration of Grails with Flex 4. I need to rework ConferenceGuide‘s administration backend to make it more ergonomic so that we can cover more events, and ever since I discovered Flex 4 niceties, I couldn’t think of doing that with anything else. The problem is that none of the existing plugins suited my needs. All of them cover Flex 3 only, some of them introduce a lot of complexity for CRUD generation, some of them use GraniteDS instead of BlazeDS, and the simplest plugin, grails-flex has never gone further than the experimental stage. I did a lot of experiments, talked a lot about it on Grails mailing lists, until Tomas Lin kindly explained to me that maybe I was approaching it the wrong way. I wanted a plugin that would set up a complete environment for Flex developement right in the middle of my Grails application. And I wanted that because I wanted to avoid using Flash Builder (you know… Eclipse… ierk!), mainly because the only advantage of Flex Builder 3 over IntelliJ Idea was the visual designer. But he was right, I was wrong. Flash Builder 4 DOES change everything. It does include a lot of very interesting features that greatly improve Flex development productivity, especially when it comes to integration with backend technologies. And for those features, I can only admit that IntelliJ is not up to par yet. I’m still gonna use it for the Grails part, but Flash Builder will be my environment of choice for Flex 4.
So, once I learnt more about Flex 4, BlazeDS 4 and Flash Builder 4 beta 2, it was time to reconsider my approach and develop a much simpler Grails plugin so that any Grails application could be used in combination with Flash Builder. I just released grails-blazeds plugin to do just that. Here is how it works:
- Install grails-blazeds plugin: “grails install-plugin blazeds”. This plugin copies a couple of configuration files into your application and imports all of the required libraries, including BlazeDS 4 and Spring-BlazeDS integration 1.5, both in nightly snapshot versions, since they have not been officially released yet
- Create a service to be exposed to your Flex application over AMF, or choose an existing one
- Add @RemotingDestination annotation to your service class, and @RemotingInclude annotation to all of the methods in this service that you wish to expose
- Edit web-app/WEB-INF/flex-servlet.xml (created when you installed the plugin): uncomment the context:component-scan element and set the base-package corresponding to your service class
- Make sure your exposed service methods don’t use Groovy classes, either as argument or return types. This is a known limitation I’m still working on, but if there are some Groovy classes here, Flash Builder doesn’t manage to generate ActionScript counterparts.
- Run your Grails application using “grails run-war” instead of “grails run-app”. Once again this is a known limitation: Flash Builder BlazeDS data connection plugin relies on a classical web app layout and doesn’t understand Grails dynamic layout (that is until someone manages to create a Grails data connection wizard for Flash Builder 4)
- In Flash Builder 4 beta 2, create a new Flex project with a J2EE server. Here are what your parameters shoud look like, “conferenceguide” being the name of my Grails application and “sarbogast” being my home directory:
- Click “Data” menu, then “Connect to BlazeDS…”
- In the “Authentication required” dialog box that appears, check “no password required” box, and click OK
- You should see your service appear, and you can select it and click Finish.
- Your service should appear in the Data/Services view. You can then compose your user interface and drag and drop your service methods to the relevant components to connect them with your Grails backend.
- Don’t forget to configure a channelset on your service:
<adminservice:AdminService id="adminService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"> <adminservice:channelSet> <s:ChannelSet> <s:AMFChannel uri="http://localhost:8080/conferenceguide/messagebroker/amf"/> </s:ChannelSet> </adminservice:channelSet> </adminservice:AdminService>
And there you go. Special thanks to James Ward, whose screencasts really helped me get it right. Now the only thing that this plugin misses, beyond the 2 known limitations, is integration with Spring Security, but this is just a start.