Using SVNANT in your ANT build files with Hudson

Tuesday, September 22, 2009

This is a quick post about a gotcha I ran into today with Hudson and SVNANT.

The Ant Target

<property name="libdir" location="lib" />
<path id="classpath">
	<fileset dir="${libdir}" includes="*.jar" excludes="svnant.jar" />
<typedef resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="classpath" />
...bunch of stuff
<svn  username="mesher" password="mesher">
	<update dir="${src}${path}"  />
...some other stuff

The Problem

I ran the Hudson build, and I got the dreaded "[echo] Error updating dev: Cannot use javahl nor command line svn client"


The first thing I did was throw this into my build file, right above the svn task:


This quickly showed me the problem: the ANT_HOME directory had svnant jars in there, and so the svn task was using those old jars and NOT the jars I had specified on my classpath.

The Solution

I did two things:

  1. Remove those jars from the lib dir of my ant install. I do not remember how they got there, but they should not have been there and were thus evicted
  2. Started using svnkit instead of javahl. Thus, the svn task now looks like this:
<svn  username="mesher" password="mesher" svnkit="true" javahl="false">
	<update dir="${src}${path}"  />


Bottom Line

Don’t let friends put svnant jars in your ant_home lib directory

JetBrains to Include MXUnit Support in CFML plug-in for IntelliJ IDEA

Wednesday, September 16, 2009

IntelliJ IDEA is a great Java IDE and the recent plugin for CFML is a nice addition to their suite. I've been following their progress and they offer a competitive commercial alternative to Eclipse flavored development. With the addition of both Flex and CFML in IDEA, this broadens the toolset and abilities for developers who would normally be coding in Java using IDEA. So, it was with excitement when I read that the talented folks at JetBrains are considering adding support for MXUnit in their CFML plugin for IDEA :

Natually, los hombres at MXUnit are always happy to discuss framework and tool integration with anyone in oder to get the best tools in the hands of developers and to support better software quality all around.

Test and be Happy!

Same Application, Multiple Locations: How I want to work

Friday, September 11, 2009

I work on 3 computers: work, home, and laptop. At home, I have VMs set up for tinkering in different operating systems. Naturally, though I do different kinds of work on each machine, there are commonalities. I use Eclipse extensively on all 3 and in the VMs. I have various app servers set up. I use Live Writer for blogging on all 3 machines. Then there’s firefox, chrome, tweetdeck. Then there’s little stuff like Notepad2 and hippoedit.

It was brought home to me recently, when I reformatted my laptop, that maintaining these apps across multiple computers is a real hassle. But it’s not just initial download and install. It’s those times where you fire up your editor, go to do something, and realize, “Oh, crap, that plugin isn’t on this machine…” Or “Wait… I thought I installed the Eclipse SWT examples. Where the hell are they? Oh, that’s right, that was at home”. Or I alt-space for Launchy, type “delicious <tab> [some search term]” and it doesn’t search my delicious bookmarks. Or I open firebug, go for the google page speed tab, and it’s not there. Or I go to Facebook and I see those damned app posts and I swear I have a greasemonkey script installed that hides those retched beasts, but there they are! Or you right click on some file in Eclipse, select “compare with local history”, and you don’t have any local history because you forgot to set the local history setting to a year instead of the default 7 days.

And databases. Don’t even get me started on databases.

It’s these little things. These things that break my flow, that break my concentration, that cost me time.

Time is money.


Time is more important than that.

At work, in an office with precious little continuous chunks of uninterrupted time to get into flow and get things done, Time is momentum.  The beancounters and bosses call it “productivity”, but they don’t really understand this anyway because they schedule daily meetings at developer-energy-happy-hour so their label for it is meaningless to me. At home, time is peace. It’s freedom. It’s when I learn. And these are what I lose when the Monkey Work slows me down.

This makes me wonder: Why does it have to be this way? Wouldn’t it be lovely to have all of these applications work like a AAA card, where the benefits follow me, not the hardware?


You fire up Eclipse, and it’s the same install that you have at work. It has the same plugins. It has the same configuration. Maybe it even has the same projects.

You fire up firefox, and it has the same extensions, themes, and greasemonkey scripts.

You alt-space, hit “sql server start”, and the damn server starts instead of being met with Launchy’s [I don’t know what you want to do so I guess you wanna search Google] because the server isn’t installed.

You create a new project on github one night after your wife goes to bed, you install the Eclipse git plugin to give it a whirl, you finally (finally!) get the damn thing configured right, you go to bed at 1:00 AM after wrestling with that alligator, and you get to work the next day, log in to Eclipse, and there it all is, waiting for you, for free (NOT money free… time free). Magic.

You go to write a new blog post inspired about being pissed off because you have to install the damn Live Writer templates plugin and recreate all your “templates” that you have at home, and… they’re already there, waiting for you. For free.

This is how I want to work.

I’m tired of maintaining installations. Images and Ghosts and VMs you carry with you do not get you this. They get you part way, but they’re “heavy” and incomplete and slow. I want it lighter, and faster, and frictionless.

I want my apps when I want them.

There are partial workarounds, but none of them get you this kind of magic.

Let’s break it down:

I reckon we are contending with at least 4 different Quantities here:

  1. The application itself
  2. The application’s “extensions”
  3. The application’s configuration (settings)
  4. The data for which the application was born to manipulate (in the case of your IDE, this would be your projects)

Sharing the application among multiple installs is generally the most difficult. Some thoughts on current solutions:

  • Keeping them on USB sticks and carrying them with you wherever you go. This is a start, but it’s far from ideal, largely because it relies on the most unreliable component in the entire equation: You.
  • For large apps like appservers and database servers, I do not know if there are any “good” solutions.
  • I could completely imagine, however, keeping Railo -- which I do not use at work but which I have to use for testing MXUnit -- in Dropbox.

Sharing extensions is easier, but still problematic. Current solutions vary based on the app (obviously), but these come to mind:

  • For Eclipse, you can export your update sites to a file, send that file to yourself (or whatever means you have of moving a file from one machine to another, like Dropbox), and then import the file. From there, you follow the normal Eclipse update process, which simply drops files into a known location on the target machine.
  • There’s also Pulse and Yoxos for Eclipse. I tried Pulse and hated it because of the stranglehold it puts on extensions. I have not tried Yoxos, though it’s possible that it's hosted service comes close to what I’m looking for.
  • For Firefox, there’s the excellent FEBE extension which will export your extensions, themes, and other stuff. From there, you follow roughly the same model as I described above for Eclipse.
  • For LiveWriter, there’s... Nothing (that I know of)
  • For Launchy, I don’t know of anything.

Sharing configuration is the easiest because so many applications at least have some facility for export.

  • You can export your bookmarks in Firefox.
  • You can export your settings for Eclipse.
  • With something like PasswordSafe, you can save your password database file anywhere and share that file.
  • For your PHP install you can share php.ini in whatever way you transport them from one machine to the next.
  • Go look in your favorite apps and see if there’s an import/export facility. Hopefully there is.

Sharing data is a quagmire. Current solutions might include:

  • For mysql, you can share the database file directories
  • For projects, at least for personal projects you might want to have installed on multiple machines, you can use svn or git hosting and get them on each machine with ease. The hurdle here is with work projects, where you don’t want to share the source code on your other machines. But you *do* want to share them across teams. Again, SCM solutions are critical here. Pulse can support this, too, though as I said I’m not a fan.
  • For SQL Server and other “enterprise-y” databases, you’re limited to .bak file export and import. For schema changes, you could use SCM or manually create transformation scripts.

So options do exist for mitigating the pain, to some extent.

There’s still pain

Still… even for apps that do provide import/export, you have to take action. You have to push (export –> transport), and you have to pull (import). You have to carve a chunk of time from the “Things I love to Do” part of your discretionary hours and sacrifice them to the Monkey Work part. And this tradeoff is where people like me bristle.

It’s not all bleak

Transport pain can, to some extent, be further reduced via Dropbox. For me, the most seamless experience I’ve had is with PasswordSafe. I had to install it on all 3 machines, but I keep my password database in my dropbox folder and so the friction is Zero. I’m considering keeping my Eclipse install in there, too, which would largely alleviate Quantities 1 and 2 (app and extensions) but not configuration. But even there, I can export the settings file to dropbox and save myself a little hassle.

I’m going to stay on the lookout for other ways I can use dropbox to share apps, extensions, and settings.

Who gets it right?

The granddaddy (to me, anyway) of data sharing is Delicious bookmarks. No, it’s not an app. But it’s still extremely useful to how I work. If applications worked like Delicious, I’d be happy.

Tweetdeck gets it right with the ability to share columns, provided you sign up for an account. Mix that with the very low friction way in which Adobe AIR handles application updates, and you’ve got a satisfactory solution. It’s a one-time install, but from there, you don’t think about it again. You don’t think about updates, and you don’t think about configuration. I like that. gets it right. But wait… they’re a website. Of course they get it right… it’s a damn website! Hear me out. I was a longtime MS Money user, and I couldn’t imagine an application that could replace what I got from Money. Then MS went and completely hosed Money with the 2008 release, which sent me looking for replacements, namely, Quicken. But Quicken couldn’t import all my data. So you know what I did… I punted. I said “I don’t care about the historical data, because I’m going to have to start from scratch anyway if I drop MS Money”. I tried out Mint, and lo and behold, it’s better than Money ever was in terms of helping me keep track of where the money goes. It’s Better! It’s faster! What?! Yes, I know, it makes no sense. But it’s superior, and I hold it up as a model of how a web app can transcend a native app. gets it right, as does Google docs, for sharing documents. This is not merely document management. These are applications that span document creation and sharing. With these apps, you do not need word processing or spreadsheet software anymore.

iTunes gets it right. I plop my iPhone in the dock and I get podcasts on my computer and phone.  Oh, wait. I can’t do that on more than one machine. Scratch that. FU, iTunes. You were so close. But you failed.

The problem with Cloud-based apps

The obvious problem with “not firing up Eclipse, but logging in to Eclipse”, is performance. Imagine if Eclipse were now a JavaFX app that, when I launched it, from any computer, would contain all my plugins, all my preferences, and potentially (ideally, configurable) my projects. Or, better yet, I login and and say “give me [my  home project set]”.  How can an app like this possibly perform as well as a native app? I do not know. I hope they figure this out.

The other clear problem is security. Do I really want my source code out there in space? OK, fine. So maybe projects themselves are optionally shareable.

Functionality is another. Sure, I can write docs with Buzzword. But can I [insert thing I can’t do here]? Nope… I can’t do mail merge. I can’t hook it into an LDAP server. I can’t do that “Track Changes” stuff with the 4 point red font in the right margin thing (or can I… it just looks different?). Perhaps functionality is one of those areas where we’re so afraid of losing a feature we think we need but when, on inspection, we really don’t, that’s keeping us from embracing this kind of technology. Perhaps the little sticky note tabs on indicating the changes from one version to the next are, in fact, good enough.

And certainly the infrastructure cost associated with this model is a huge barrier. It quite likely won’t come without a price. But it’s a different cost. It’s money. And I’d pay money to get back my Time.

Where do we go from here?

I’d like to hear from you: how do you contend with this issue? How do you maintain applications across computers? How do you protect the stuff you want to protect and share the stuff you feel isn’t a threat to your livelihood if you lost it? And do you know of other applications that get it right? What’s out there in this amazing world that I and others don’t know about but which helps reduce the maintenance of applications across multiple machines, and even across multiple operating systems?

Considering application, extension, and configuration, how do you save Time?

Saving Insert Picture settings in Windows Live Writer

Monday, September 7, 2009

Here’s a how-to for something that’s annoyed me about Windows Live Writer since I started using it several months back.

The Problem

When inserting a picture into a Live Writer blog post, I always want to a) have the picture open in new window and b) change the linked-to picture to appear in its original size. I could not find  a way in Live Writer to set these as defaults; consequently I had to make these changes to every picture I inserted.

That. Sucks.

The Solution

Found right in the Live Writer Help:

“To apply the properties of the current picture to all pictures that you insert in the future, in the Picture pane, click the Picture tab, and then click Save settings as default.”

Sure enough… it’s there. In the bottom right. Exactly where I’d expect it not to be. But hey, who am I to complain… It’s free. And this is how you do what I wanted it to do, so ‘nuff bitching. Enjoy!


Source Code Formatting Examples

When blogging, source code formatting is a huge PITA. I’m working on an Eclipse plugin to take away some of that pain. So bear with me as I play with some formatting. There is absolutely nothing useful at all in this post. This is merely a post that I can use to continually test tweaks.

Here’s some XML:

<target name="package" depends="clean,version" description="--> packages the appropriate files into the deployment-ready zip file. use this for testing; otherwise, use publish">
	<echo message="building ${zipfile}. basedir is  ${basedir}" />
	<zip destfile="${zipfile}" casesensitive="false">
		<zipfileset dir="${basedir}" 
			prefix="mxunit" casesensitive="false" />

And here’s some Java:

private static String getCommonWhitespacePrefix(String[] lines){
	//get rid of any completely blank lines, as they will throw off the getCommonPrefix function
	List<String> newLines = new ArrayList<String>();
	for (int i = 0; i < lines.length; i++) {
	return StringUtils.getCommonPrefix(newLines.toArray(new String[newLines.size()]));

And some lovely ColdFusion

<cffunction name="_MixinAll" access="public">
	<cfargument name="objReceiver" required="true" hint="the object to receive the functions">
	<cfargument name="objGiver" required="true" hint="the object whose functions will be mixed in">
	<cfargument name="includedMethods" required="false" default="" hint="pass a list of methods; otherwise, all are included">
	<cfset var md = getMetadata(objGiver)>
	<cfset var a_functions = md.functions>
	<cfset var fn = 1>

	<cfset arguments.objReceiver._Mixin = _Mixin>
	<cfset arguments.objGiver._getComponentVariable = _getComponentVariable>

	<cfloop from="1" to="#ArrayLen(a_functions)#" index="fn">
		<cfif (arguments.includedMethods eq "" OR listFindNoCase(arguments.includedMethods,a_functions[fn].name))>
			<cfset arguments.objReceiver._Mixin(a_functions[fn].name,	arguments.objGiver._getComponentVariable(a_functions[fn].name))>

And some javascript, just to prove it looks OK

	if (window.XMLHttpRequest)
		req = new XMLHttpRequest();
	else if (window.ActiveXObject)
		while (!req && Spry.Utils.msProgIDs.length)
			try { req = new ActiveXObject(Spry.Utils.msProgIDs[0]); } catch (e) { req = null; }
			if (!req)
				Spry.Utils.msProgIDs.splice(0, 1);

How'd all that look?