<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en" xml:base="http://www.symphonious.net/wp-atom.php">
	<title type="text">Symphonious</title>
	<subtitle type="text">Living in a state of accord.</subtitle>

	<updated>2010-01-30T13:39:54Z</updated>
	<generator uri="http://wordpress.org/" version="2.9.1">WordPress</generator>

	<link rel="alternate" type="text/html" href="http://www.symphonious.net" />
	<id>http://www.symphonious.net/feed/atom/</id>
	

			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/symphonious" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="symphonious" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Auto-update is a Killer Technology]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/30/auto-update-is-a-killer-technology/" />
		<id>http://www.symphonious.net/?p=1302</id>
		<updated>2010-01-30T13:39:54Z</updated>
		<published>2010-01-30T13:39:54Z</published>
		<category scheme="http://www.symphonious.net" term="Code and Geek Stuff" />		<summary type="html"><![CDATA[
       There’s a huge amount of new technology pouring out into the world these days &#8211; lots of it focussed around the web and consumers and the key term that keeps being talked about it ubiquity. Flash brought video to the web because it was ubiquitous, HTML5 will kill [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/30/auto-update-is-a-killer-technology/">&lt;p&gt;
       There’s a huge amount of new technology pouring out into the world these days &amp;#8211; lots of it focussed around the web and consumers and the key term that keeps being talked about it ubiquity. Flash brought video to the web because it was ubiquitous, HTML5 will kill flash once it’s ubiquitous, mobile web access is becoming ubiquitous etc. The most striking thing in all of this is just how quickly these new technologies are actually finding their way into real world usage.
    &lt;/p&gt;
    &lt;p&gt;
       The path to ubiquity is suddenly an awful lot shorter than it ever has been. Take for example the rate of upgrades from IE 6 to IE 7, compared with IE 7 to IE 8. Flash support for H.264 is comparatively new but it’s now ubiquitous. Anyone supporting FireFox 1.0 anymore? What about 2.0? The upgrade cycle is so fast that the range of older tech needing to be supported has shrunk dramatically in the past few years.
    &lt;/p&gt;
    &lt;p&gt;
       How has all this happened? Auto-update became standard.
    &lt;/p&gt;
    &lt;p&gt;
       When IE 6 was first release, I’m not sure if Windows Update existed or not, but it certainly wasn’t turned on by default. Not so long before that, downloading software updates was really quite uncommon &amp;#8211; you went to the store and bought the upgrade. These days, it’s &lt;em&gt;expected&lt;/em&gt; that software includes an auto-update function and you assume it will be on by default or at least ask on first start up.
    &lt;/p&gt;
    &lt;p&gt;
       The best example of this that I know of is actually Java. &lt;a href="http://editlive.com"&gt;EditLive!&lt;/a&gt; still supports the ancient and no-longer-supported-by-Sun Java 1.4, not because we like it but because it’s a key customer requirement and it keeps showing up in real usage. Java 1.4 didn’t include an auto-update mechanism, so it’s users had to take specific action to upgrade it and most of them didn’t care. Java 1.5 on the other hand, &lt;em&gt;did&lt;/em&gt; add auto-update and as a result, while it still turns up a fair bit, it’s almost always at the latest 1.5 release and the same goes for Java 6.  And that’s with the terrible upgrade experience Java provides.
    &lt;/p&gt;
    &lt;p&gt;
       The thing is, this rate of upgrading is only going to increase. iPhone software for example is updated incredibly rapidly because it all comes through the App Store and the more users see upgrades happening smoothly and successfully, the more they trust it to happen so the more frequently they’ll do it. Not to mention the more they’ll be willing to accept software that just silently updates itself.
    &lt;/p&gt;
    &lt;p&gt;
       For developers, this changes the way to view the world. It’s actually viable in many cases to target just the latest version of many new technologies because it’s easier for users to upgrade and more likely they’ll do it either now or at least very soon. It also means that things like the Flash vs HTML5 debate change quite significantly &amp;#8211; the time required for the HTML5 tech to become ubiquitous enough is probably shorter than most people expect, much of it is already there. So the argument that Flash will have moved on by the time HTML5 catches up is a lot weaker than history would make it seem.
    &lt;/p&gt;
    &lt;p&gt;
       Look out a bit further than today and start thinking of the power that this auto-update brings. Imagine the world in say 5 years time &amp;#8211; it’s likely that by then IE 6 market share will be small enough to be ignored by most or all people. So everyone would have upgraded to a browser of today’s standard or better &amp;#8211; significantly, with a solid auto-update program. How likely do you think it will be that there’s significant market-share for anything but the latest and &lt;em&gt;maybe&lt;/em&gt; second latest major release of a browser? That would mean that new web technologies would be rolled out to effective ubiquity within one or two years. Potentially much quicker if they’re released in a minor update which is also increasingly common.
    &lt;/p&gt;
    &lt;p&gt;
       The same thing is being outside outside of web technologies as well &amp;#8211; in roughly everything except desktop OS’s.  The bottom line is that developers have never had it better and can leverage newer and better platforms sooner to deliver more features, more easily. All thanks to the unnoticed workhorse that is auto-update.
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/oDtVKfeST8E" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/30/auto-update-is-a-killer-technology/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/30/auto-update-is-a-killer-technology/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[On Funny Variable Names]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/27/on-funny-variable-names/" />
		<id>http://www.symphonious.net/?p=1300</id>
		<updated>2010-01-27T11:41:05Z</updated>
		<published>2010-01-27T11:41:05Z</published>
		<category scheme="http://www.symphonious.net" term="Code and Geek Stuff" />		<summary type="html"><![CDATA[
       Emmanuel Lécharny &#8211; Pick good names for your methods/data structures…
    
    
      
         5 years later, when I come back into this crap, I have *no* bloody idea about [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/27/on-funny-variable-names/">&lt;p&gt;
       Emmanuel Lécharny &amp;#8211; &lt;a href="http://hrabal.blogspot.com/2010/01/pick-good-names-for-your-methodsdata.html"&gt;Pick good names for your methods/data structures…&lt;/a&gt;
    &lt;/p&gt;
    &lt;blockquote&gt;
      &lt;p&gt;
         5 years later, when I come back into this crap, I have *no* bloody idea about what is what. Is Twix for the frontend or the backend ?
      &lt;/p&gt;
      &lt;p&gt;
         &lt;em&gt;When you pick a name, and when you think it&amp;#39;s funny, just think about those, and probably you, who will not have fun at all when it&amp;#39;ll be time to fix some code in this area, with no clue about what Twix and Snickers are&amp;#8230;&lt;/em&gt;
      &lt;/p&gt;
    &lt;/blockquote&gt;
    &lt;p&gt;
       Oh yeah, been there, got burnt by that…
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/JHN3x6vO_5g" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/27/on-funny-variable-names/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/27/on-funny-variable-names/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Using Ivy for Dependency Management]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/25/using-ivy-for-dependency-management/" />
		<id>http://www.symphonious.net/?p=1297</id>
		<updated>2010-01-25T14:59:30Z</updated>
		<published>2010-01-25T14:59:30Z</published>
		<category scheme="http://www.symphonious.net" term="Build Systems" />		<summary type="html"><![CDATA[
       At first glance, Ivy looks like a re-implementation of Maven’s dependency management that works nicely with ant, and to some degree it is, but it also adds some pretty significant improvements and some pretty significant complexity.
    
    
     [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/25/using-ivy-for-dependency-management/">&lt;p&gt;
       At first glance, &lt;a href="http://ant.apache.org/ivy/"&gt;Ivy&lt;/a&gt; looks like a re-implementation of Maven’s dependency management that works nicely with ant, and to some degree it is, but it also adds some pretty significant improvements and some pretty significant complexity.
    &lt;/p&gt;
    &lt;h3&gt;
       Maven Compatibility
    &lt;/h3&gt;
    &lt;p&gt;
       Firstly, Ivy is compatible with Maven repositories, so if you think the way Maven manages dependencies is perfect, but don’t want to buy into the rest of Maven, Ivy provides a good answer. The configuration is a little bit different and you’ll have to learn a little bit about Ivy’s configurations which are both more powerful and more complex than Maven’s dependency “scope”, but you won’t have to go too far into them.
    &lt;/p&gt;
    &lt;p&gt;
       Ivy will use the Maven 2 repository by default so all the same libraries are available &amp;#8211; complete with all the metadata problems.
    &lt;/p&gt;
    &lt;h3&gt;
       Ivy Configurations
    &lt;/h3&gt;
    &lt;p&gt;
       Configurations are probably the biggest difference between Ivy and Maven’s dependency management. At the simplest level they are roughly equivalent to setting the scope attribute in Maven. It lets you choose whether a library is required only for compilation, if it should be included in the packaged WAR/EAR or if it’s used only for testing. Since Ivy doesn’t actually build the project, what a configuration means is a lot more flexible than what I scope means in Maven. Each Ivy setup needs to setup the configurations it needs from scratch and it’s up to the Ant build process to ensure the libraries are used as intended.
    &lt;/p&gt;
    &lt;p&gt;
       If you import a project from the Maven repository, Ivy will convert the various scopes into the following configurations:
    &lt;/p&gt;
    &lt;table border="1" width="100%" cellspacing="0" cellpadding="0" class="PrimaryBordersTable"&gt;
      &lt;tr&gt;
        &lt;th id="id_6273"&gt;
          Name
        &lt;/th&gt;
        &lt;th id="id_6274"&gt;
          Description
        &lt;/th&gt;
        &lt;th id="id_6275"&gt;
          Example Library
        &lt;/th&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          default
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          runtime dependencies and master artifact can be used with this conf
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
           
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          master
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          contains only the artifact published by this module itself, with no transitive dependencies
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          The project’s jar itself
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          compile
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this is the default scope, used if none is specified. Compile dependencies are available in all classpaths
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          commons-lang
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          provided
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          Servlet APIs
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          runtime
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          An AOP runtime library?
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          test
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          JUnit
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          system
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          ??
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          sources
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this configuration contains the source artifact of this module, if any
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          Source for the project
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          javadoc
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          this configuration contains the javadoc artifact of this module, if any
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          JavaDoc for the project
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td headers="id_6273"&gt;
          optional
        &lt;/td&gt;
        &lt;td headers="id_6274"&gt;
          contains all optional dependencies
        &lt;/td&gt;
        &lt;td headers="id_6275"&gt;
          Anything optional
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
    &lt;p&gt;
       The three most commonly used configurations for dependencies are compile, provided and test &amp;#8211; most projects will only ever need to add dependencies in those categories. The master, sources and javadoc configurations typically don’t contain any dependencies, they are used for publishing the results of the build into &amp;#8211; the same configurations defined here are used by other projects that depend on this one. The default configuration is provided to make this easy, by including all the runtime dependencies and the project’s jar itself in one configuration.
    &lt;/p&gt;
    &lt;p&gt;
       It’s also worth nothing that configurations can extend each other. In the Maven import, runtime extends compile so any libraries you compile against are also available at run time. Default extends runtime and master. You could of course ignore the extends functionality and just include multiple lib dirs on the classpath within your normal ant script as you would if the jars were directly checked in to source control, but the functionality is reasonably simple and makes it very explicitly clear what jars are on what classpath&lt;a class="footnote" id="footlink1:1264424269169" href="#footnote1:1264424269169"&gt;1&lt;/a&gt;.
    &lt;/p&gt;
    &lt;p&gt;
       My approach has been to stick with these configurations &amp;#8211; they’re simple enough but cover every conceivable situation that I can currently imagine. The only real difference I’m not currently using the master configuration &amp;#8211; the produced jars are just put directly into default. That means you can’t easily require the library without any dependencies, but it means that the defaults can be used for what most libraries produce (a single jar file with the same name as the project and in the default configuration).
    &lt;/p&gt;
    &lt;h3&gt;
       Ivy Repositories
    &lt;/h3&gt;
    &lt;p&gt;
       Ivy has it’s own concept of a repository that uses Ivy descriptor files instead of the Maven POM files and gives the full power, flexibility and complexity of Ivy’s configuration concepts. The configurations might be handy, but what I find most useful, is the fact that Ivy supports multiple different types of repositories.  So instead of having to run specific software to provide the repository, it can be accessed via sftp, ssh, a shared drive or even subversion. This makes setting up your own repository significantly easier &amp;#8211; it’s quite likely you already have a server that’s available via ssh somewhere. I also like the fact that the whole Ivy configuration can be included in the project itself, so once you check out the source code, you have all the config settings you need to be able to build it&lt;a class="footnote" id="footlink2:1264426193822" href="#footnote2:1264426193822"&gt;2&lt;/a&gt;.
    &lt;/p&gt;
    &lt;h4&gt;
       Importing Libraries
    &lt;/h4&gt;
    &lt;p&gt;
       Ivy can pull libraries from the public maven repository and import them into your private one which makes it reasonably quick to spin up a private repository and get rid of the dependency on the public one altogether. However, it’s still a fairly slow process and takes up the bulk of the time required to get Ivy up and running.  That said, it immediately solves a &lt;em&gt;lot&lt;/em&gt; of headaches about incorrect meta-data or missing libraries in the maven repository.
    &lt;/p&gt;
    &lt;p&gt;
       What I found was missing however, was a simple tool to add new libraries that don’t exist in the Maven repository. For a single jar, it’s pretty easy to create the directory structure and an ivy.xml file for it, but when you have a large number like the GData APIs, it can take up a huge amount of time.  I whipped up a simple bash script to work out most of the meta-data from a jar file (module name and version number), create the directory structure and a simple ivy.xml file then upload it to the repository. It doesn’t add the dependencies automatically but that’s easy once the directory structure and basic ivy.xml has been created.
    &lt;/p&gt;
    &lt;h4&gt;
       Namespaces
    &lt;/h4&gt;
    &lt;p&gt;
       One of the most common problems with the Maven repository is the number of Apache libraries that still use the Maven 1 naming scheme. For example Commons IO is available under &lt;em&gt;both&lt;/em&gt; the org.apache.commons group &lt;em&gt;and &lt;/em&gt;the commons-io group. To Maven and Ivy, the different groups mean it’s actually a different library so it can potentially wind up on the classpath twice. When you import libraries from the Maven repository, ivy lets you configure namespaces to avoid this problem.  Essentially, Ivy will rewrite the group name to consistently use one or the other, resulting in a more consistent repository and no duplicate jars on the classpath. The rename is done both for the imported library and anything else you import that depends on it so things automatically point to the right place.
    &lt;/p&gt;
    &lt;h3&gt;
       Actual Usage
    &lt;/h3&gt;
    &lt;p&gt;
       Actually using Ivy is really quite straight forward.  There are a lot of different ant tasks you can use, largely due to the huge amount of flexibility Ivy provides, but you can also keep it quite straight forward.  I’ve got five basic uses at the moment:
    &lt;/p&gt;
    &lt;ol&gt;
      &lt;li&gt;
        configure &amp;#8211; I’m calling this outside of any target at the moment so it always happens before anything else.  It sets up Ivy using the configuration file designed for this project.  So it has the right configurations set up and points to the private repository instead of the default Maven one.
      &lt;/li&gt;
      &lt;li&gt;
        retrieve &amp;#8211; actually calculate the dependencies and link them into the specified directories.  Each configuration gets the jar files placed in it’s own sub-directory.  From then on, to use the dependencies in the ant script, just point at the appropriate directory.  I also set this to use symlinks when possible so the files actually stay in Ivy’s cache directory and it just creates a symlink to save some time.
      &lt;/li&gt;
      &lt;li&gt;
        Inline retrieves &amp;#8211; the retrieve task can also be configured to retrieve a library that you specify directly via attributes instead of in an ivy.xml file.  This is really handy for things that the build scripts itself want to use, like a scala compiler or cobertura. Otherwise each project would have to have the same dependencies.
      &lt;/li&gt;
      &lt;li&gt;
        Import &amp;#8211; I have an ant task set up specifically to make it easy to import libraries from the Maven repository.  It uses a slightly different settings file (which includes the Maven repository) and prompts for the group, module and revision to import.
      &lt;/li&gt;
      &lt;li&gt;
        buildlist &amp;#8211; this is a handy little task for building sub-modules within a project. It looks at each project’s dependencies and calculates the correct build order which you can then pass in to subant.  Very much like the Maven reactor.
      &lt;/li&gt;
    &lt;/ol&gt;
    &lt;p&gt;
       The nice thing is that Ivy just plugs in to your existing ant file without many changes at all.
    &lt;/p&gt;
    &lt;h3&gt;
       Tracking Versions
    &lt;/h3&gt;
    &lt;p&gt;
       Ivy has some nice ideas for working with versions which I haven’t found in Maven before though they may exist. Firstly, it can generate a build number by looking at the latest version available in the repository and adding one which is much better than having a normal ant buildnumber file on a shared drive somewhere.  Secondly, when Ivy published an artifact to the repository, it rewrites the ivy.xml to include the specific version of dependencies that it was built with, so anything that depends on it will get known good libraries, even if it was using a SNAPSHOT style build.  In Ivy the SNAPSHOT version is equivalent to latest.integration, but it always generates some form of version number when the build is published, so you never get a latest.integration version in the repository.  By default it uses a date stamp which actually works out really well.
    &lt;/p&gt;
    &lt;p&gt;
       Aside from latest.integration you can also specify a range of restrictions for acceptable versions which is handy but probably too complex to be worth the effort in most cases.  Ivy already resolves most version conflicts automatically by evicting the older versions which works fine as long as the libraries maintain backwards compatibility&lt;a class="footnote" id="footlink3:1264429445570" href="#footnote3:1264429445570"&gt;3&lt;/a&gt;. So when commons-httpclient requires commons-logging 1.0 but commons-io requires commons-logging 1.1, you wind up with just commons-logging 1.1 on the classpath and everything works.
    &lt;/p&gt;
    &lt;h3&gt;
       Sharing Projects and Modules
    &lt;/h3&gt;
    &lt;p&gt;
       Ultimately, the main reason I was looking to move away from jar files in source control was to make it easy to share modules between different projects. Right now, that would basically have to be done by either forking the code, occasionally building a jar and dropping it in or using svn:externals &amp;#8211; none of which are particularly appealing.  With Ivy, the buildlist can handle any submodule being dumped into the project directory and you can pull a version of the module from the repository regardless of whether or not you have the source code checked out for it. There are now two modes you can use sub-modules in:
    &lt;/p&gt;
    &lt;ol&gt;
      &lt;li&gt;
        Just declare it as a dependency and Ivy will grab the version from the repository. Just like including a jar in source control but a little easier.
      &lt;/li&gt;
      &lt;li&gt;
        Declare it as a dependency and check out a copy of the source as a submodule of the project you’re currently working on. This then gets picked up by the Ivy buildlist task and automatically inserted in the right place in the build process.  Now you can easily make changes to the module and use them in your outer project without doing a full release.  You only need to push a new version into the shared repository when you’ve got the bugfix or new API completely sorted out and ready for others to use. In the mean time, everything still builds with a single execution of ant.
      &lt;/li&gt;
    &lt;/ol&gt;
    &lt;h3&gt;
       Speed
    &lt;/h3&gt;
    &lt;p&gt;
       The project I tested this out on has a lot of dependencies &amp;#8211; it took ages to import them all into the private repository, many required manually fixing up metadata problems as well. With the jar files in subversion, the build server could check out the full source (including libraries) and build the project in 3-4 minutes (the build server and the subversion repository have a gigabit connection between them). The first build it did with Ivy took the build time up to about 25 minutes as it downloaded all the dependencies (the Ivy repository was in the US, the build server was in Australia), but because Ivy keeps a local cache of everything it downloaded the second build went back down to the usual 3-4 minutes.
    &lt;/p&gt;
    &lt;p&gt;
       Ivy can be a bit slow at calculating dependencies though I probably wouldn’t have noticed it if the project didn’t have as many submodules, each of which require Ivy to calculate the dependencies before building in. In the grand scheme of things though, the time that Ivy spends working out dependencies is small enough to be insignificant compared to whatever the rest of the build is doing. Since the jar files are just dropped in to a normal directory, it’s also easy to add a flag to completely skip Ivy and use the existing dependencies if you do have small tasks that are run really frequently. With a remote subversion server you can waste &lt;em&gt;far&lt;/em&gt; more time updating, moving or deleting jar files.
    &lt;/p&gt;
    &lt;h3&gt;
       Summary
    &lt;/h3&gt;
    &lt;p&gt;
       I think Ivy is a pretty clear winner.  It’s simple to set up a private repository and avoid all the common problems people hit with the Maven repository, what complexity Ivy adds can be isolated to the template build scripts so individual projects stay quite simple and with buildlist it’s now easy to share modules between projects which had been causing me a lot of headaches.
    &lt;/p&gt;
    &lt;p&gt;
       The downside: there’s a reasonable amount of learning that the team will have to take on and at first glance Ivy looks like it adds more complexity than benefit so getting buy-in isn’t a guarantee.
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink1:1264424269169" id="footnote1:1264424269169"&gt;1&lt;/a&gt; &amp;#8211; once you “resolve” the dependencies you can simply look in the appropriate directory and see all the jar files for that configuration in one place&lt;a class="footnotereturn" href="#footlink1:1264424269169"&gt;↩&lt;/a&gt;
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink2:1264426193822" id="footnote2:1264426193822"&gt;2&lt;/a&gt; &amp;#8211; I also put the Ivy jar files in subversion so that it’s available and doesn’t need to be installed separately. So the requirements to build are just a JDK, ant and a checked out source tree&lt;a class="footnotereturn" href="#footlink2:1264426193822"&gt;↩&lt;/a&gt;
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink3:1264429445570" id="footnote3:1264429445570"&gt;3&lt;/a&gt; &amp;#8211; and if they don’t you’re in a lot of trouble as the project that wanted the newer version is unlikely to work with an older version anyway.&lt;a class="footnotereturn" href="#footlink3:1264429445570"&gt;↩&lt;/a&gt;
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/gDRuqP9ScYY" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/25/using-ivy-for-dependency-management/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/25/using-ivy-for-dependency-management/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Ant, Subant and Basedir]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/25/ant-subant-and-basedir/" />
		<id>http://www.symphonious.net/?p=1294</id>
		<updated>2010-01-25T10:09:31Z</updated>
		<published>2010-01-25T10:08:51Z</published>
		<category scheme="http://www.symphonious.net" term="Build Systems" /><category scheme="http://www.symphonious.net" term="Code and Geek Stuff" />		<summary type="html"><![CDATA[
       Here’s an important lesson for people combining ant scripts &#8211; the way basedir is calculated is very unlikely to be what you expect. In particular, if you combine the &#60;ant&#62; task with the &#60;subant&#62; task you’re probably in for a surprise.
    
    [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/25/ant-subant-and-basedir/">&lt;p&gt;
       &lt;img alt="Apache Ant logo" width="115" height="75" src="http://www.symphonious.net/wp-content/uploads/2010/01/project-logo_6038245254255283799.gif" style=" float: left;" /&gt;Here’s an important lesson for people combining ant scripts &amp;#8211; the way basedir is calculated is very unlikely to be what you expect. In particular, if you combine the &amp;#60;ant&amp;#62; task with the &amp;#60;subant&amp;#62; task you’re probably in for a surprise.
    &lt;/p&gt;
    &lt;p&gt;
       I learnt this important life lesson when the improved build scripts I’d been working on failed on the build server even though it worked perfectly on my machine. The difference is that the build server is running cruise control and it has a wrapper ant script which checks out a fresh copy of the project then uses the &amp;#60;ant&amp;#62; task to build it. The ant task was:
    &lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#60;ant antfile=&amp;quot;build.xml&amp;quot; target=&amp;quot;dist&amp;quot; dir=&amp;quot;projectDir&amp;quot; /&amp;#62;&lt;/code&gt;
&lt;/pre&gt;
    &lt;p&gt;
       As far as that main antfile is concerned, everything is perfect &amp;#8211; the basedir is the directory that it’s build.xml is in and all is good with the world. However, if that build.xml happens to use subant, the basedir &lt;em&gt;will not be changed&lt;/em&gt;. Basically, basedir is now a user configured property rather than a calculated value so it doesn’t get changed. However, if you instead use:
    &lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&amp;#60;ant antfile=&amp;quot;projectDir/build.xml&amp;quot; target=&amp;quot;dist&amp;quot; /&amp;#62;&lt;/code&gt;
&lt;/pre&gt;
    &lt;p&gt;
       It all works out. The main build.xml still gets the basedir as projectDir but when it uses subant, the basedir will be automatically changed to whatever directory the build file subant points to is in.
    &lt;/p&gt;
    &lt;p&gt;
       The behavior is explained in &lt;a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=29658"&gt;this bug report&lt;/a&gt; which is closed as WONTFIX for backwards compatibility. Thankfully ant 1.8 adds a useNativeBasedir attribute which provides much more predictable basedir behavior for the ant task.
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/99GkQ2PqfFg" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/25/ant-subant-and-basedir/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/25/ant-subant-and-basedir/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Three Types of Ant Scripts]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/22/three-types-of-ant-scripts/" />
		<id>http://www.symphonious.net/?p=1292</id>
		<updated>2010-01-22T09:27:22Z</updated>
		<published>2010-01-22T09:27:22Z</published>
		<category scheme="http://www.symphonious.net" term="Build Systems" />		<summary type="html"><![CDATA[
       Bryan comments on the three types of ant scripts:
    
    
      
         In my experience, there are three types of Ant scripts that you encounter &#34;in the wild&#34;:
  [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/22/three-types-of-ant-scripts/">&lt;p&gt;
       &lt;a href="http://bryanpendleton.blogspot.com/2010/01/ant-version-18-is-nearing-release.html"&gt;Bryan comments on the three types of ant scripts&lt;/a&gt;:
    &lt;/p&gt;
    &lt;blockquote&gt;
      &lt;p&gt;
         In my experience, there are three types of Ant scripts that you encounter &amp;quot;in the wild&amp;quot;:
      &lt;/p&gt;
      &lt;ul&gt;
        &lt;li&gt;
          Small Ant scripts, generally Java-only, which can use most of Ant&amp;#39;s default behaviors and are clear and simple. A lot of open source build scripts are this way.
        &lt;/li&gt;
        &lt;li&gt;
          Serious commercial Ant scripts written before macrodef and import became available. These are generally impossible to understand and evolve, and the reality is that a small cadre of Build Wizards keep them running. Such systems often involve a substantial number of custom Ant tasks.
        &lt;/li&gt;
        &lt;li&gt;
          Serious commercial Ant scripts written to use macrodef and import. In my experience, the need for custom Ant tasks drops way off with Ant releases post-1.6.
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/blockquote&gt;
    &lt;p&gt;
        This really does ring true to me.  Ant scripts can fairly quickly become unwieldy and difficult to work with if you aren’t using import and macrodef, but with them you can achieve so much more without the complexity getting out of hand. They won’t absolve you of the need to properly understand ant and the declarative paradigm it wants you to work with, but it’s much more approachable.
    &lt;/p&gt;
    &lt;p&gt;
       If I can ever get someone to add the optional dependencies for scripting support on our build servers&lt;a class="footnote" id="footlink1:1264152423184" href="#footnote1:1264152423184"&gt;1&lt;/a&gt; I may well find they help a lot too.
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink1:1264152423184" id="footnote1:1264152423184"&gt;1&lt;/a&gt; &amp;#8211; which happen to be Windows boxes, behind a firewall on the other side of the world from me, so not easy to make remote changes on &lt;a class="footnotereturn" href="#footlink1:1264152423184"&gt;↩&lt;/a&gt;
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/76YpQvD-1ak" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/22/three-types-of-ant-scripts/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/22/three-types-of-ant-scripts/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Apache Pivot]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/21/apache-pivot/" />
		<id>http://www.symphonious.net/?p=1289</id>
		<updated>2010-01-21T10:56:28Z</updated>
		<published>2010-01-21T10:56:05Z</published>
		<category scheme="http://www.symphonious.net" term="Code and Geek Stuff" /><category scheme="http://www.symphonious.net" term="General" />		<summary type="html"><![CDATA[
       Thanks to a tweet from @bdelacretaz I discovered Apache Pivot today. It does indeed have a nice website, and the library itself looks great. It’s pitched as an RIA framework and mostly seems focussed on browser based deployment via applets. However, pivot apps can also be deployed as [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/21/apache-pivot/">&lt;p&gt;
       Thanks to a tweet from &lt;a href="http://twitter.com/bdelacretaz/status/8019996240"&gt;@bdelacretaz&lt;/a&gt; I discovered &lt;a href="http://pivot.apache.org/"&gt;Apache Pivot&lt;/a&gt; today. It does indeed have a nice website, and the library itself looks great. It’s pitched as an RIA framework and mostly seems focussed on browser based deployment via applets. However, pivot apps can also be deployed as standalone applications which is where I think it’s most promising.
    &lt;/p&gt;
    &lt;p&gt;
       The killer feature as far as I can see, is the much richer set of components that are available, combined with a better set of customisation points such as effects, transitions, web queries and data binding. There are libraries to do most or all of this with Swing, but since it wasn’t designed for it up front, they tend to feel pretty clunky and “bolted-on”. Hopefully Pivot can avoid that.
    &lt;/p&gt;
    &lt;p&gt;
       Sadly, it does look a bit like you’re leaving Swing completely behind &amp;#8211; if for no reason other than the look and feel is unlikely to match nicely with the Pivot themes without a lot of effort. While Pivot has a lot of components built-in, there are a vast world of custom Swing components around and it would be nice if you could leverage those.
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/UzBL92YsUNc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/21/apache-pivot/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/21/apache-pivot/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Better File System APIs]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/21/better-file-system-apis/" />
		<id>http://www.symphonious.net/?p=1285</id>
		<updated>2010-01-21T08:33:00Z</updated>
		<published>2010-01-21T08:28:19Z</published>
		<category scheme="http://www.symphonious.net" term="Code and Geek Stuff" /><category scheme="http://www.symphonious.net" term="Java" />		<summary type="html"><![CDATA[
       Dylan complained about the lack of testability with file system APIs, which reminded me of a neat looking library I stumbled across while looking at build systems: EntityFS. Among a bunch of other useful sounding things it provides:
    
    
   [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/21/better-file-system-apis/">&lt;p&gt;
       &lt;a href="http://techtangents.wordpress.com/2010/01/20/filesystems/"&gt;Dylan complained about the lack of testability with file system APIs&lt;/a&gt;, which reminded me of a neat looking library I stumbled across while looking at build systems: &lt;a href="http://www.entityfs.org/"&gt;EntityFS&lt;/a&gt;. Among a bunch of other useful sounding things it provides:
    &lt;/p&gt;
    &lt;blockquote&gt;
      &lt;span class="Apple-style-span" style=" border-collapse: separate; color: rgb(0, 0, 0); font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"&gt;&lt;span class="Apple-style-span" style=" font-family: serif; line-height: 20px; text-align: left;"&gt;File system APIs are backend-independent. File systems can be created in RAM memory, on Zip files, on file system directories, etcetera&lt;/span&gt;&lt;/span&gt;
    &lt;/blockquote&gt;
    &lt;p&gt;
       Sadly it’s under the LGPL which makes it difficult if you happen to sell to big enterprises that are still somewhat scared of GPL type licenses, but they’re nowhere near as common as they used to be. I should note though that Holocene Software are offering commercial licenses for an undisclosed price.
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/ZPdMn69M8J8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/21/better-file-system-apis/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/21/better-file-system-apis/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Comparing Build Systems]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/11/comparing-build-systems/" />
		<id>http://www.symphonious.net/?p=1274</id>
		<updated>2010-01-11T13:51:33Z</updated>
		<published>2010-01-11T12:58:10Z</published>
		<category scheme="http://www.symphonious.net" term="Build Systems" />		<summary type="html"><![CDATA[
       After spending some time thinking about and using different build systems, I can’t say I really like any of them all that much. I know have a reasonably complex project, using submodules that can be built with ant, buildr, maven and gradle &#8211; with varying degrees of support [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/11/comparing-build-systems/">&lt;p&gt;
       After spending some time &lt;a href="http://www.symphonious.net/2010/01/04/on-build-systems/"&gt;thinking about&lt;/a&gt; and using different build systems, I can’t say I really like any of them all that much. I know have a reasonably complex project, using submodules that can be built with ant, buildr, maven and gradle &amp;#8211; with varying degrees of support for the Ephox specific requirements and reporting.
    &lt;/p&gt;
    &lt;h3&gt;
       &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;
    &lt;/h3&gt;
    &lt;p&gt;
       Ah, the Java world’s favorite whipping boy. The more I play with Maven, the more I start to understand why it gets such a bad wrap: it’s too easy to get started and do it all wrong. Maven is not a build tool that is quick to start using &amp;#8211; it requires planning, common conventions, a number of extras systems such as repository servers be set up and templates to be designed. However, Maven does an unfortunately good job of working if you just create a simple pom.xml and run mvn.
    &lt;/p&gt;
    &lt;p&gt;
       If you want Maven to work reliably though, you need to set up a bunch of stuff:
    &lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;
        Private repository servers, including vetting all the meta-data that goes into it. Don’t just import the central Maven repository.
      &lt;/li&gt;
      &lt;li&gt;
        A company specific parent POM. This should specify explicit versions for each Maven plugin, point the project at the private repository servers and anything else that is standard across the company.
      &lt;/li&gt;
      &lt;li&gt;
        Build plugins for anything custom you need. Real Maven plugins are the best way to extend things &amp;#8211; trying to put it all in your pom.xml or similar build scripts rapidly gets too complex and unmaintainable.
      &lt;/li&gt;
      &lt;li&gt;
        Strictly follow the Maven way.
      &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;
       Make no mistake, that’s a lot of work, but it sets up a very robust, enterprise build system and most of it only needs to be done once for the entire company, so starting a project from then on does become pretty simple.
    &lt;/p&gt;
    &lt;p&gt;
       All in all, it’s more work than I really want to take on &amp;#8211; especially the building of custom plugins. Ephox doesn’t follow the Maven way strictly enough either &amp;#8211; the most problematic area being how to release and version snapshots.
    &lt;/p&gt;
    &lt;h3&gt;
       &lt;a href="http://buildr.apache.org/"&gt;Buildr&lt;/a&gt;
    &lt;/h3&gt;
    &lt;p&gt;
       Lots of people talk about using rake to build Java projects, but rake by itself simple doesn’t know enough about Java to really shine. Buildr is a layer over rake that adds Java knowledge. I actually quite like Buildr and think it has a fair bit of promise.
    &lt;/p&gt;
    &lt;p&gt;
       It can use the Maven repository for dependencies, so if you go that way you need to set up your own private repository again. Support for Thankfully, Buildr can also use plain jar files so if you don’t want to go the repository route, you don’t have to. The big downside is how complex it can be to get transitive dependencies working &amp;#8211; partly by design and partly due to bugs and current limitations.
    &lt;/p&gt;
    &lt;p&gt;
       Buildr can run on either C-Ruby or JRuby. Start-up is faster on C-Ruby, but JRuby can run things like Javac without spawning a new JVM, so it fairly quickly starts to make up the time difference. Installing either version is quite easy.
    &lt;/p&gt;
    &lt;p&gt;
       It is a little odd to be writing the build script for a Java project in Ruby. The language difference doesn’t really matter, but having a different set of libraries for things like IO and file system stuff is an unfortunate overhead. If you’re using Ruby in some other form, it’s no problem, otherwise it’s extra training and ramp-up cost.
    &lt;/p&gt;
    &lt;p&gt;
       I also had a &lt;em&gt;lot&lt;/em&gt; of problems because Buildr was including stuff on the test classpath by default. Some version of JUnit and JMock are meant to be included, but it varies between versions and the documentation doesn’t always match up with what happens. Given that JMock 2 is very much incompatible with JMock 1.3, it didn’t go so well. The odd thing is that Buildr can be quite flexible &amp;#8211; it supports TestNG and a few other libraries, but with JUnit it really wants to also use JMock. There is a way to specify a different version, but the group name is hard coded, so you can’t go back to JMock 1.3 because it has a different group name&lt;a class="footnote" id="footlink1:1263215332489" href="#footnote1:1263215332489"&gt;1&lt;/a&gt;. It would be far better for Buildr to just leave the mock framework as a dependency the project developer has to add if they want it.
    &lt;/p&gt;
    &lt;p&gt;
       Overall, Buildr is a pretty good solution, it’s quick and easy to get up and running (beware the central repository though) but it’s still fairly immature which caused me a fair few problems. The good news is that every issue I ran into was already a known problem that the Buildr team is working on resolving, so it’s pretty likely to become a very good option in the future.
    &lt;/p&gt;
    &lt;h3&gt;
       &lt;a href="http://www.gradle.org/"&gt;Gradle&lt;/a&gt;
    &lt;/h3&gt;
    &lt;p&gt;
       Gradle is a particularly interesting project. It feels a lot like a Java-oriented version of Rake with elements of Buildr, Maven and Ant mixed in. It has the best ant integration story of any of the non-ant build tools. Like Buildr it can pretty seamlessly utilise ant tasks but within the scripting language rather than with XML. Gradle can also import an existing ant build file and use the targets it defines as if they were native. That’s surprisingly powerful and useful, especially if you already have various build scripts and utilities written in ant.
    &lt;/p&gt;
    &lt;p&gt;
       Gradle also has a really nice approach to multi-project builds, allowing you to inherit configuration from the parent build script and pull in project dependencies easily. However, it’s not all smooth sailing. The main project build file starts to get pretty complex because it winds up configuring both itself and the sub-modules in the one file. The inheritance doesn’t really make sense if you have a mix of sub-module types, say some Java, some Scala and some just web resources. In hindsight, it would probably be better to ignore the built-in inheritance and just use normal file import functionality within each module to select the default module behavior to use.
    &lt;/p&gt;
    &lt;p&gt;
       Sadly, the multi-project stuff really came crashing down because of some pretty unexpected behavior about what the current project actually was. Depending on when a particular bit of script gets accessed, it might take project() to mean the current sub-module or it might wind up referring to the last sub-module that gets processed. It made sense when you think through the way the code works, but it’s far from intuitive when you’re just trying to build your project. I really couldn’t see myself recommending Gradle until this is significantly simplified and made intuitive.
    &lt;/p&gt;
    &lt;p&gt;
       Gradle also handles transitive dependencies much better than Buildr, though I had some confusion of when dependencies were transitive and when they weren’t. Gradle is one of the most flexible tools in terms of how dependencies are handled &amp;#8211; using either the maven repository, ivy or defining dependencies as groups directly in the build files, allowing you to check jar files directly into svn if you prefer.
    &lt;/p&gt;
    &lt;p&gt;
       Gradle was also one of the slowest of the tools I tried. Once it’s up and running, build times are equivalent to ant, but a do-nothing target took just over 4 seconds whereas ant took well under a second. For a full build, that’s not a big deal &amp;#8211; a project that ant builds in 2 minutes would take gradle 2 minutes and 4 seconds. The problem is when you’re running a really simple task as part of some development (e.g. trying to remove duplication that simian had flagged).
    &lt;/p&gt;
    &lt;h3&gt;
       &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;
    &lt;/h3&gt;
    &lt;p&gt;
       I’m beginning to think Ant should have been called Cockroach instead &amp;#8211; at the end of the build tool war, you can bet ant will still be there going strong. It’s really quite scary that it’s been around for about 10 years now and is up to version 1.8, and not for lack of maintainers. Ant doesn’t use convention over configuration &amp;#8211; you have to code up your entire build by piecing together the task building blocks it provides. That said, the tasks ant provides are it’s key strength &amp;#8211; powerful, flexible and in almost every case very well designed &amp;#8211; piecing together a build process from ant tasks is &lt;em&gt;much &lt;/em&gt;simpler than piecing together one from scratch or with command line stuff like make would use.
    &lt;/p&gt;
    &lt;p&gt;
       Since you’re writing the whole build script yourself though, ant files can become very long winded and hard to maintain. If you want to use ant successfully, you have to build a set of base scripts that provide the kind of standard project system that tools like Maven and Gradle give you. The benefit being that you can build it the way you want, not the way the tools want you to, without ever having to fight the tool.
    &lt;/p&gt;
    &lt;p&gt;
       Thankfully, Ant actually has some pretty powerful tools to build up that project system. It’s simple to import other build files so you can break your script up, and it’s simple to use extension points by overriding targets in the actual project build file. Ant 1.8 adds ‘extension-point’ to make this even easier, but it’s quite good even without that. It’s not quick to build up the right structure but like the infrastructure required for Maven, you can probably share your ant templates company wide (or perhaps much further). &lt;a href="http://www.easyant.org/"&gt;Easyant&lt;/a&gt; seems to be an attempt to provide a ready-made project convention on top of ant, but I think it went a bit too far and buried the ant functionality too deeply.
    &lt;/p&gt;
    &lt;p&gt;
       What I wound up with is a set of build scripts that define various useful macros and targets &amp;#8211; version numbering, tagging in subversion, working with dependencies on sub-modules &amp;#8211; and a set of scripts that define module types such as jar, war and the parent project. Frankly, that approach has revolutionised the way I work with ant.
    &lt;/p&gt;
    &lt;p&gt;
       The build scripts are now basically a first class project in and of themselves. They can be re-used across multiple projects and improved over time as different projects have various needs. Those improvements can then be easily shared back with the original projects since the scripts aren’t being copied into every project, just treated like any other dependency.
    &lt;/p&gt;
    &lt;p&gt;
       The build files in the project and sub-module are then very short and simple, since they only have to define any non-standard behavior and the required dependencies. This makes the build process for the project much simpler to maintain and understand. It obviously makes it much easier to start a new project or module as well.
    &lt;/p&gt;
    &lt;p&gt;
       I also found it really useful to define macros to make things more readable. For example, many but not all projects need to include a copy of EditLive! so there’s a set of predefined targets to grab the right version and make it available. Targets that need EditLive! just depend on the “editlive” predefined target, but that doesn’t allow a specific version of EditLive! to be requested. So there’s also a macro defined, editlive-version, that lets you set the version to use. All it does is set a few properties that control where to get EditLive! from, but the final syntax is much easier to read the the previous method of putting them directly in a properties file allowed. I may be overusing the technique at the moment, but it’s quite useful&lt;a class="footnote" id="footlink2:1263216861633" href="#footnote2:1263216861633"&gt;2&lt;/a&gt;.
    &lt;/p&gt;
    &lt;p&gt;
       However, there are some drawbacks. It got fairly difficult to keep track of which properties were declared at which points in the build &amp;#8211; especially as the number of build files being imported increased. There were a few builds tagged as ${version-major}.${version-minor} because of that. Fortunately, that confusion was limited to within the build framework I was building &amp;#8211; not the actual build files for the project itself, and I found that it was mostly caused by my habit of defining every variable in a properties file that’s included at the top of the build script. For build frameworks, it’s a lot better to declare properties as late as possible, within targets. That way, the property is set at the same time as the first work related to it is being done and any dependent information would already be set. Essentially, it uses the target dependencies to work out the right order for setting properties.
    &lt;/p&gt;
    &lt;p&gt;
       The downside of building this framework is that now we have to maintain it ourselves as well &amp;#8211; it would be much nicer to use something like Maven or Gradle and have their dev teams deal with the on-going maintenance. However, since we do have some Ephox specific stuff, we’ll always be maintaining some amount of build infrastructure and since we’re currently maintaining it separate for every project, this approach is a lot better than the status quo.
    &lt;/p&gt;
    &lt;h3&gt;
       Conclusion
    &lt;/h3&gt;
    &lt;p&gt;
       Ultimately, I think that ant is still the best choice, but it really is vital to set up a build framework that you can reuse, rather than doing everything from scratch for each project. Buildr and Gradle look like they have some huge potential in the future though, but they need some more time to improve stability, simplicity and consistency. I’d guess that their version 2.0’s will be something pretty serious to reckon with. Maven is an awesome tool but it just requires too much effort to get it working right. However, the consistency in how a project is built that the Maven project has brought to the Java would is absolutely revolutionary &amp;#8211; neither Buildr or Gradle could be anywhere near as simple as they are if it weren’t for the work and evangelism of the Maven team to embed the Maven way in to the Java world’s consciousness. Sure we’re still fighting over many parts of it, but &lt;a href="http://www.symphonious.net/2010/01/06/project-directory-structure/"&gt;the Maven project structure is now well established and a very powerful convention&lt;/a&gt;.
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink1:1263215332489" id="footnote1:1263215332489"&gt;1&lt;/a&gt; &amp;#8211; that pesky Maven 1 to Maven 2 transition again…&lt;a class="footnotereturn" href="#footlink1:1263215332489"&gt;↩&lt;/a&gt;
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink2:1263216861633" id="footnote2:1263216861633"&gt;2&lt;/a&gt; &amp;#8211; I would also note that the greatest improvement ever added to ant is the &lt;em&gt;else&lt;/em&gt; attribute on the condition task (in ant 1.6.2). Makes it much easier and more maintainable to set a property value to one of two options. &lt;a class="footnotereturn" href="#footlink2:1263216861633"&gt;&lt;em&gt;↩&lt;/em&gt;&lt;/a&gt;
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/oFr-XlYvvZU" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/11/comparing-build-systems/#comments" thr:count="4" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/11/comparing-build-systems/feed/atom/" thr:count="4" />
		<thr:total>4</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Know when to refine, when to refactor and when to refrain]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/11/know-when-to-refine-when-to/" />
		<id>http://www.symphonious.net/?p=1279</id>
		<updated>2010-01-11T10:08:50Z</updated>
		<published>2010-01-11T09:53:24Z</published>
		<category scheme="http://www.symphonious.net" term="General" />		<summary type="html"><![CDATA[
       Chris J Davis in Lessons for the Newly Minted:
    
    
      As you can clearly see, when you have tight deadlines, and mountains of work, refactoring existing code that works is highly unadvisable. As a developer you [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/11/know-when-to-refine-when-to/">&lt;p&gt;
       &lt;a href="http://www.chrisjdavis.org/lessons-for-the-newly-minted"&gt;Chris J Davis in Lessons for the Newly Minted&lt;/a&gt;:
    &lt;/p&gt;
    &lt;blockquote&gt;
      As you can clearly see, when you have tight deadlines, and mountains of work, refactoring existing code that works is highly unadvisable. As a developer you must make strategic decisions about where your time is spent, and this must be informed and balanced by the needs of the company. Should you strive to craft breathtakingly beautiful code? Yes, but not at the expense of the overall velocity of your development schedule. Sometimes good enough is beautiful.
    &lt;/blockquote&gt;
    &lt;p&gt;
       Amen to that.
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/dQIgFga35PQ" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/11/know-when-to-refine-when-to/#comments" thr:count="4" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/11/know-when-to-refine-when-to/feed/atom/" thr:count="4" />
		<thr:total>4</thr:total>
	</entry>
		<entry>
		<author>
			<name>Adrian Sutton</name>
						<uri>http://www.symphonious.net</uri>
					</author>
		<title type="html"><![CDATA[Project Directory Structure]]></title>
		<link rel="alternate" type="text/html" href="http://www.symphonious.net/2010/01/06/project-directory-structure/" />
		<id>http://www.symphonious.net/?p=1272</id>
		<updated>2010-01-06T19:05:55Z</updated>
		<published>2010-01-06T19:05:55Z</published>
		<category scheme="http://www.symphonious.net" term="Build Systems" />		<summary type="html"><![CDATA[
       Having spent a bunch of time looking at various build systems and tools, one of the simplest and most effective improvements I’ve discovered is to always use the Maven project structure. It doesn’t matter if you’re not using Maven, there’s no downside to using it and every build [...]]]></summary>
		<content type="html" xml:base="http://www.symphonious.net/2010/01/06/project-directory-structure/">&lt;p&gt;
       Having spent a bunch of time looking at various build systems and tools, one of the simplest and most effective improvements I’ve discovered is to always use the Maven project structure. It doesn’t matter if you’re not using Maven, there’s no downside to using it and every build tool that uses convention over configuration uses the Maven structure.
    &lt;/p&gt;
    &lt;p&gt;
       Previously I’ve been of the opinion that the directory structure really didn’t matter much &amp;#8211; I went with whatever happened to be auto-generated by whatever tool I was using that day. There is a small overhead in remembering to look for the JavaSource directory instead of src or source when you switch projects but it’s incredibly minimal and not worth worrying about on its own.  When it comes to build scripts, getting these basics in the same place saves a whole lot of configuration and makes everything simpler.
    &lt;/p&gt;
    &lt;p&gt;
       When you start using sub-modules within the project it really becomes clear just how much time you can waste tweaking bits of build script to work with even slightly different directory structures. Not only do many build systems give you more functionality automatically, you suddenly get the ability to re-use build scripts and templates across different modules and across projects.
    &lt;/p&gt;
    &lt;p&gt;
       Don’t think that using the Maven directory structure means you have to play by all the Maven rules though.  You can still generate more than one artifact from a project if that suits you best, you can check jar files into source control rather than using a repository etc, but source files go in src/main/java (or scala or groovy or webapp etc) and test files go in src/test/java (or scala or groovy etc).
    &lt;/p&gt;
    &lt;p&gt;
       Simple,quick and easy to switch to&lt;a class="footnote" id="footlink1:1262804739903" href="#footnote1:1262804739903"&gt;1&lt;/a&gt; and saves a surprising amount of setup work in your build scripts &amp;#8211; especially when you first get the project up and running.
    &lt;/p&gt;
    &lt;p class="footnote"&gt;
       &lt;a href="#footlink1:1262804739903" id="footnote1:1262804739903"&gt;1&lt;/a&gt; &amp;#8211; assuming your current build scripts aren’t completely sadistic &lt;a class="footnotereturn" href="#footlink1:1262804739903"&gt;↩&lt;/a&gt;
    &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/symphonious/~4/TfuCFklxXG8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://www.symphonious.net/2010/01/06/project-directory-structure/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://www.symphonious.net/2010/01/06/project-directory-structure/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	</entry>
	</feed><!-- Dynamic page generated in 0.324 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-02-09 01:39:16 -->
