Continuous Integration with Flex, Hudson, and ArcGIS Server, Part 1

(Part 2, Part 3, Part 4)

I’ve been meaning to blog about our findings with getting CI going for Flex, since I took time to whinge about it earlier.  It was a bit of a journey, but all in all, not that bad.  Much of the thanks goes to Hudson, which is, how you say?, super-fantastic.  I plan to break this into a few blog posts rather than one big-old doozy.   The parts (I think) will be along the lines of:

  1. Getting your Fles project building with ant and Flex Builder, parts 1 and 2.
  2. Setting up unit testing with Fluint.
  3. Setting up Hudson.

Whachoo Need (OOH)

This post is focused on getting your Flex Builder project building with ant.  As such, I presume you are using Flex Builder, but if you aren’t and just want to build with ant, you should be OK. Oh, and I am doing this on Winders, even though ant is usually the domain of the Unix-based Java wanks (I mean “wanks” as a term of endearment, like “I love those wanks”)

Go get the following and download to your computer:

  • ANT – The original builder.  It can carry, like, 10,000 times its own weight in builds.  Unzip it to c:\ant.
  • Flex Ant Tasks – These come with the Flex SDK, which comes with Flex Builder.  You can find them in C:\Program Files (x86)\Adobe\Flex Builder 3\sdks\3.2.0\ant\lib\flexTasks.jar.  If you don’t have Flex Builder, go download the SDK and put it somewhere.
  • ArcGIS Server Flex API – So we can get our map on, know what I’m saying? (I am using 1.2)

Create the Project

Open Flex Builder and create a new project.  I am presuming that your local workspace is c:\projects\FlexCI, though it really doesn’t matter.

So, we’ll start by creating a new Flex Project in Flex Builder.

Create Flex Project

Hit ‘Next’ in the project wizard and we have our project.  Copy the AGS Flex API swc into your libs folder (see pic).

flexapi

Now we can make a map and stuff.  Add the following code to your app:

<esri:Map>
     <esri:ArcGISTiledMapServiceLayer
          url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
</esri:Map>

Now we have our map.  In Flex Builder, build (Ctrl+B, unless you are using ‘Build Automatically’) the site and run it, you should see a map of our world.  Building with Flex Builder works, which was a requirement for me.  I wanted people to be able to build and debug in the IDE, but also quickly build from the command line with ant.  I like Flexibility, #rimshot.

High Apple Pie in the Sky Hopes

In order to build with ant, we need a couple of items

  • A build file, we will call build.xml
  • A properties file, we will call build.properties

I am not about to go into the gory details of how ant works, but presume you know the basics, which is all I know.  We need to define a build target that compiles our Flex project.  The steps the build file will go through are:

  1. Clean out the build dir.
  2. Build the project.

In ant-speak, that is two targets.  I will call them ‘init’ and ‘build-flex-project’.  For the init target, we just need to delete everything in the directory that Flex Builder set up as the deploy location, which is (by default) the bin-debug directory.  Create a build.xml file in your Flex Project root, has the following XML:

<project name='Flex Ant Tasks Build Script' default=”init”'>
    <!-- delete and redeploy -->
    <target name='init'>
        <delete includeemptydirs='true'>
            <fileset dir='bin-debug' includes='**\*' />
        </delete>
    </target>
</project>

This is a fully-functional ant script now.  Test it by opening a command prompt, switching to the project directory, and typing ‘c:\ant\bin\ant’ (minus the quotes, of course)  You should see something like:

firstant

Also, your bin-debug directory should be empty.  WOOHOO!  If you build with Flex Builder again (you may have to “Clean” since FB won’t build unless it detects a change) the files will go back into the bin-debug dir.  Right, now let’s get the build part going.  Adobe was nice enough to create ant tasks that will build Flex projects.  The easiest way to make them available to your ant script is to:

  1. Copy the flexTasks.jar file into your c:\ant\lib folder.
  2. Reference these tasks in your build.xml file.

The second part is done by adding the following code to the top of the build.xml file:

<!-- points to are flexTasks.jar -->
<taskdef resource='flexTasks.tasks' />

That’ll do it.  (NOTE:  In a real CI scenario, which we’ll get to, we would not copy the jar into the ant\lib folder, but make it part of the project artifacts and reference it locally.  Bear with me, baby steps on the bus…)

Now, let’s add the build-flex-project target, which uses the mxmlc Flex ant task.

<target name='build-flex-project' depends='init'>
     <mxmlc file='${srcpath.dir}/${application.name}.mxml' output='${deploypath.dir}/${application.name}.swf'>
           <load-config filename='${FLEX_HOME}/frameworks/flex-config.xml'/>
           <include-libraries file='${libs.dir}' />
     </mxmlc>
</target>

WHOA!  OK, so I’ve jumped ahead a bit, so lemme ‘splain.  First off, we tell ant that this target depends on the init target, so it will run init before running the build.  Second, those funky ${} items that you see are properties.  So, you can see that I have one for”:

  • srcpath.dir – the source directory, so we knows what to build.
  • FLEX_HOME – this is where our SDK lives
  • deploypath.dir – where to put the build output
  • libs.dir – where are external libraries (like the AGS Flex API) live
  • application.name – What do we want our SWF to be called.

Now we need to put these properties somewhere, and the aforementioned build.properties file is where they belong.  Looks like:

#Copy this file locally to build.properties and change below for your env

# change this to your Flex SDK directory path
FLEX_HOME=C:/Program Files (x86)/Adobe/Flex Builder 3/sdks/3.2.0

# this points to your project's src directory
# {$basedir} is a default variable that can be used in any Antscript
# and it points to the project's root folder [ flex_ant_pt1_Tasks ]
# in this case
srcpath.dir =${basedir}/src

# points to the project's libs directory
libs.dir =${basedir}/libs

# this is the folder we want to publish the swf to
deploypath.dir = ${basedir}/bin-debug

application.name=FlexAGSCI

We need to tell our build.xml file about the build properties file, and we do so by adding this to the top (meaning, first thing under the <project> opening tag):

<!-- load properties file -->
<property file='build.properties'/>

The last thing we need before running the build again is to change the default target to build-flex-project.  You’ll find the default attribute on the root project element.

Now, running ‘c:\ant\bin\ant’ (btw, putting c:\ant\bin in your PATH is advisable, then you could just type ‘ant’) at the command line, gives:

secondant

Look in your bin-debug folder, and you’ll see the SWF file, which should be fully functional.

I think I’ll stop today’s post there.  It has gotten a bit long on me (they always do).  The next post will cover how to get the rest of the files that Flex Builder creates, like the HTML wrapper and Flash-detecting javascript files, incorporated into the build.

Hope this is useful.

Advertisements

About Ruprict

I am a nerd that is a Nerd Wannabe. I have more kids than should be allowed by law, a lovely wife, and a different sense of humor than most. I work in the field of GIS, where I am still trying to find myself on the map. View all posts by Ruprict

14 responses to “Continuous Integration with Flex, Hudson, and ArcGIS Server, Part 1

  • Jonathan Hartley

    Hey.

    I’m really going to have to sit down and try to understand what all this build configuration sort of stuff gives you that ‘make all’ didn’t have covered thirty years ago – and still works perfectly for today. I must be doing it wrong, please feel free to tell me what I’m missing.

    • Ruprict

      Hullo Hartley.

      The short answer is, nothing. This post is a bit below your pay grade, though, Mr. Tartley. The audience consists of people like myself that can’t get to ‘make all’ and, frankly, don’t understand it. ant is a well-accepted build tool, like make, I guess. I would argue it’s a bit easier to mess with than make, but I’d be standing on one leg since I don’t know the first thing about make or how you would get it going to build Flex. I could ask you the question of why you are using Python and not assembler, expecting your answer to be “It’s just easier”

      I do know that Hudson will use ant natively, whereas make would have to be the black box from Hudson’s perspective.

      Cheers

  • Jonathan Hartley

    Hey Ruprict,

    [disclaimer: I’m not very good at ‘not being a dick’, nor at recognizing when I am being one, especially when discussing opinions that differ about topics like this, so please try to help me out by being forgiving if I inadvertently stray over the line. Call me on it and I’ll be endlessly apologetic. Thanks!]

    [2nd disclaimer: I’ve just got back from the pub]

    I do not know ‘the one true way’. I only know the way I currently do it. Other ways are no doubt equally valid, or even better in many regards. I have never even used most of the tools you talk about, except maybe for a week or two here and there. I’m curious about the lack of overlap, and what we can learn from each other.

    It seems surprising to me how there are real sorts of ‘islands of understanding’, and people naturally gravitate towards one island or another. I find ‘make’ and its ilk to be simpler than ant and the resulting complexities. I can see that a lot of other people don’t agree. I find myself increasingly fascinated these days by what different people consider to be ‘easy’ or ‘hard’, and with the successes and failures of communication that contribute towards this.

    I may be way off base here, but I get a feeling in the back of my mind. I’d be interested to see where you disagree: Command-line utils such as ‘make’ do come with an initial complexity in getting started. Creating a Makefile is harder than pressing F5 to build. But it doesn’t seem (to me) any harder than the sort of config you outline above. However, this initial complexity is repaid many times over in terms of how easy subsequent tasks then become. It saves on complexity overall. To my mind, that’s exactly the reason why command-line interfaces* are so great. Once you start using it for everything, then everything (automated builds, integration servers, running all tests, logging test results in a database) becomes a simple one-line command. You could run them from a .bat file if you want double-clickiness. It’s win-win-win.

    (* not Windows’ out-of-the-box command-line interface. That needs replacing)

    Clearly most people don’t agree. I may simply be doing it wrong.

    Maybe I should just write my own series of blog posts about how I would approach this, and see if I am able to make them half as good as your own.

    For the record, my pay grade is strictly in the ‘negligible’ category, as befitting my ‘just a programmer’ station. 🙂

    Hugs!

    Jaybes

  • ruprict

    I don’t disagree with the fantasticness of command line utils. I use Cygwin on a daily basis for that very reason. I almost exclusively use svn and git at the command line as well. The MS cmd is horrific, as you say (Console2 makes it a bit better)

    Something like ant gives me a command line build, outside of the IDE. The point of this series is to get the build and tests running at the command line, and then telling Hudson to just run those commands. Hudson really just becomes another user that builds every time someone commits source.

    Oh, and I wouldn’t use a .bat file on a dare. I’d likely write a rake task or something, if I could.

    No need for disclaimers, Tartley. Just announce my Quake superiority over yourself and we’ll call it even….

    Rups

  • Jonathan Hartley

    Oh, you’re *such* a douche! How can anybody *live* like that? Get away, before I get any on me!

    Oh alright, you have total Quake superiority.

    Over NOBODY!!!! !!

  • Jonathan Hartley

    ruprict1>> I don’t know the first thing about make

    ruprict3>> I’d likely write a rake task

    Isn’t ‘rake’ a replacement for ‘make’? Ahar! I didn’t know it was useful outside of Ruby, or indeed Rails for that matter. Intruiging.

  • vineet

    when i tried to run the code above for displaying a map. I am getting an error saying prefix “esri” for element “esri:map” is not bound. Can you suggest something.

  • vineet

    Thanks I have included the library and got the code running. I am new to flex and arcgis. I find this really confusing. I will try to explain my problem. I have installed arcgis server on my system and also have flex builder3 and arc_gis api for flex installed. There are some maps (.mxd files) created in arc map. When i tried to create a web application using arcserver it is taking lot of time to run in the browser. How can the flex api help me to run them faster.

  • Continuous Integration with Flex, Hudson, and ArcGIS Server, Part IV « Fumbling Towards Geekstacy

    […] in ArcDeveloper, Continuous Integration, Flex. Tags: Continuous Integration, Flex trackback (Part 1, Part 2, Part […]

  • Continuous Integration with Flex, Hudson, and ArcGIS Server, Part 2 « Fumbling Towards Geekstacy

    […] August 4, 2009 Posted by ruprict in Agile, Continuous Integration, Flex. trackback In the last post, I talked about the very basics of getting a Flex project going with Flex Builder and ant.  […]

  • Continuous Integration with Flex, Hudson, and ArcGIS Server, Part 3 « Fumbling Towards Geekstacy

    […] and ArcGIS Server, Part 3 August 24, 2009 Posted by ruprict in Uncategorized. trackback (Part 1 and Part […]

  • Continuous Integration with Flex, Hudson, and ArcGIS Server-Part V « Fumbling Towards Geekstacy

    […] Server-Part V December 11, 2009 Posted by ruprict in Continuous Integration. trackback (Part 1, Part 2, Part 3,Part […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: