<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5193038868300749464</id><updated>2012-02-07T09:43:36.492-08:00</updated><category term='ruby'/><category term='scripting'/><category term='visual'/><category term='Darwin'/><category term='Lisp Java Groovy Ruby'/><category term='tech'/><category term='stephen king'/><category term='iterm'/><category term='beyond'/><category term='apple'/><category term='programming'/><category term='Intellij IDEA'/><category term='Amazon'/><category term='mount'/><category term='finder'/><category term='diff'/><category term='machine'/><category term='S3'/><category term='zsh z-shell unix'/><category term='Java Development'/><category term='Java'/><category term='osx'/><category term='tomcat spring debugging logging log4j commons-logging'/><category term='applescript tiling'/><category term='Groovy'/><category term='OS X'/><category term='time'/><category term='software development'/><category term='AWS'/><category term='applescript'/><category term='resume'/><category term='groovy MarkupBuilder markup builder xml cdata'/><category term='capsule'/><category term='terminal'/><category term='fixed'/><category term='window'/><category term='rails'/><category term='compare'/><category term='spaces'/><category term='darwinports'/><category term='macports'/><category term='failure'/><category term='java groovy scripting'/><category term='EC2'/><category term='13949712720901ForOSX'/><category term='tiling'/><category term='backup'/><category term='OSX Leopard Spaces solved java'/><title type='text'>devilelephant</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>40</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6902032051512894261</id><published>2011-04-05T09:05:00.000-07:00</published><updated>2011-04-14T06:45:42.095-07:00</updated><title type='text'>Fixing iChat GoogleTalk (gchat) connection issues.</title><content type='html'>iChat kept dropping my two Google chat accounts so I did some of my own Googling for a fix:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Create a script to reconnect iChat.&lt;/h3&gt;&lt;br /&gt;I created a file '~/dev/ichat-reconnect.sh':&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/osascript&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if appIsRunning("iChat") then&lt;br /&gt;&amp;nbsp;tell application "iChat"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if status is offline then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log in&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end if&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set originalStatus to the status message&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end tell&lt;br /&gt;end if&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;on appIsRunning(appName)&lt;br /&gt;&amp;nbsp;tell application "System Events" to (name of processes) contains appName&lt;br /&gt;end appIsRunning&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Create a LaunchAgent&lt;/h3&gt;&lt;br /&gt;LaunchAgents are the OSX equivalent of cron jobs.&lt;br /&gt;&lt;br /&gt;In the folder ~/Library/LaunchAgents/ I created a file 'com.ichat.reconnect.plist':&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;!DOCTYPE&amp;nbsp;plist&amp;nbsp;PUBLIC&amp;nbsp;"-//Apple//DTD&amp;nbsp;PLIST&amp;nbsp;1.0//EN"&amp;nbsp;"http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;&lt;br /&gt;&amp;lt;plist&amp;nbsp;version="1.0"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;dict&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;label&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;string&gt;com.ichat.reconnect&amp;lt;/string&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;ProgramArguments&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;array&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;string&gt;/Users/gcoller/dev/ichat-reconnect.sh&amp;lt;/string&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/array&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;OnDemand&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;false/&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;Nice&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;integer&gt;1&amp;lt;/integer&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;StartInterval&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;integer&gt;5&amp;lt;/integer&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;StandardErrorPath&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;string&gt;/tmp/AlTest1.err&amp;lt;/string&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;key&gt;StandardOutPath&amp;lt;/key&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;string&gt;/tmp/AlTest1.out&amp;lt;/string&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/dict&gt;&lt;br /&gt;&amp;lt;/plist&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Basically it means run my ichat-reconnect.sh script every 5 seconds.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Tell launch agent about your file&lt;/h3&gt;&lt;br /&gt;Issue the command:&lt;br /&gt;&lt;br /&gt;launchctl load com.ichat.reconnect.plist&lt;br /&gt;&lt;br /&gt;To get it started. It will start automatically on reboots.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6902032051512894261?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6902032051512894261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6902032051512894261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6902032051512894261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6902032051512894261'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2011/04/fixing-ichat-googletalk-gchat.html' title='Fixing iChat GoogleTalk (gchat) connection issues.'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-3622687296632467849</id><published>2011-03-17T11:34:00.000-07:00</published><updated>2011-03-17T11:37:17.638-07:00</updated><title type='text'>Intellij IDEA: Key command for right-click context menu</title><content type='html'>Ever wanted that right-click menu without having to touch the mouse when using IDEA?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note: This is for OS X, probably is available for Windows.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Turns out to be easy enough: &lt;/div&gt;&lt;div&gt;1) Open KeyMap in Settings&lt;/div&gt;&lt;/div&gt;&lt;div&gt;2) Find "Show Context Menu" in the "Other" folder&lt;/div&gt;&lt;div&gt;3) Assign it a key (I used F13 since it is easy to find and available)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-3622687296632467849?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/3622687296632467849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=3622687296632467849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3622687296632467849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3622687296632467849'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2011/03/intellij-idea-key-command-for-right.html' title='Intellij IDEA: Key command for right-click context menu'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6709941189263582455</id><published>2011-01-05T13:09:00.001-08:00</published><updated>2011-01-05T13:13:30.201-08:00</updated><title type='text'>Groovy to Scala: Closures</title><content type='html'>Defining a closure that takes two variables and returns a String.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span style="font-weight:bold;"&gt;Groovy: &lt;/span&gt;&lt;br /&gt;&lt;code&gt;{ x, y -&gt; ...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Scala: &lt;/span&gt;&lt;br /&gt;&lt;code&gt;(x:Stirng, y:String):String =&gt; { ... }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note, Scala requires types for values x and y.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6709941189263582455?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6709941189263582455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6709941189263582455' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6709941189263582455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6709941189263582455'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2011/01/groovy-to-scala-closures.html' title='Groovy to Scala: Closures'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-7990330008935151167</id><published>2011-01-05T12:02:00.000-08:00</published><updated>2011-01-05T12:18:34.636-08:00</updated><title type='text'>Groovy to Scala: Regular Expressions</title><content type='html'>Coming to Scala from Groovy/Java.  Scala seems to have a bit more overhead in learning basic concepts so I'm planing on keeping my notes here in a series of short posts.  This is not meant by any means to be comprehensive but just a "hello world" for each topic that I wish I had.&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Regular Expressions:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Defining: Just add a ".r" after a normal string:&lt;/div&gt;    &lt;code&gt;&lt;br /&gt;    val regEx = "apple*".r&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Using: Use in a typical Scala match statement:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    val name = ....&lt;br /&gt;  name match {&lt;br /&gt;  &amp;nbsp;&amp;nbsp;case regEx =&gt; // do your processing here&lt;br /&gt;  &amp;nbsp;&amp;nbsp;case entry =&gt; // like default, possibly throw an error&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Grouping: &lt;/div&gt;&lt;code&gt;&lt;br /&gt;val zipMatch = "(\\d+)-(\\d+)"&lt;br /&gt;val zip = "12345-1234"&lt;br /&gt;zip match {&lt;br /&gt; &amp;nbsp;&amp;nbsp;case regEx(num1, num2) =&gt; // num1 == 12345, num2 == 1234&lt;br /&gt; &amp;nbsp;&amp;nbsp;case entry =&gt; // do nothing&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-7990330008935151167?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/7990330008935151167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=7990330008935151167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7990330008935151167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7990330008935151167'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2011/01/groovy-to-scala-regular-expressions.html' title='Groovy to Scala: Regular Expressions'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6542280813792833015</id><published>2008-07-25T10:44:00.000-07:00</published><updated>2008-07-25T10:48:17.635-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stephen king'/><title type='text'>Stephen King's N</title><content type='html'>      &lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="340" height="450" id="theN_widget" align="middle"&gt;&lt;br /&gt;        &lt;param name="allowScriptAccess" value="always"&gt;&lt;br /&gt;        &lt;param name="movie" value="http://simonschuster.gigya.s3.amazonaws.com/simonschuster/fla/then.swf?gid="&gt;&lt;br /&gt;        &lt;param name="quality" value="high"&gt;&lt;br /&gt;        &lt;param name="bgcolor" value="#172737"&gt;&lt;br /&gt;        &lt;embed src="http://simonschuster.gigya.s3.amazonaws.com/simonschuster/fla/then.swf?gid=" quality="high" bgcolor="#172737" width="340" height="450" name="theN_widget" align="middle" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;br /&gt;      &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6542280813792833015?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6542280813792833015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6542280813792833015' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6542280813792833015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6542280813792833015'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2008/07/stephen-kings-n.html' title='Stephen King&apos;s N'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-2340829079107175525</id><published>2008-07-25T09:41:00.000-07:00</published><updated>2008-07-25T09:55:44.750-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='S3'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='EC2'/><category scheme='http://www.blogger.com/atom/ns#' term='AWS'/><title type='text'>Amazon S3 Fast downloads to EC2 using Curl</title><content type='html'>Our company is building an application that depends heavily on Amazon's Cloud Web Services: Simple Storage Service, Elastic Compute Cloud, and Simple Queue Service.  We are using Java for a lot of the business logic and Groovy for the 'glue code', interacting with frameworks, etc.&lt;br /&gt;&lt;br /&gt;Anyway, I've spent some time tuning downloads and found out that I can get an order of magnitude faster download time if I shell out to 'curl' than if I use jets3t or the lower-level HttpClient.  Note this speed-up only occurs when moving an S3 object to an EC2 instance, not when moving it outside the cloud (to my laptop for instance).&lt;br /&gt;&lt;br /&gt;For some reason uploads using jets3t are very fast and we are guessing at this point that HttpClient (which jets3t depends upon) is causing the slowdown because it either can't (or hasn't been configured properly to) deal with the extra-large packet sizes that AWS allows within its cloud.&lt;br /&gt;&lt;br /&gt;Being a developer on a schedule I punted and shelled out to curl using a signed-url that jets3t provides for my S3 Object get.&lt;br /&gt;&lt;br /&gt;Here is the pseudo-code in Groovy (would be trivial to convert to plain Java) for the shell-out:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;S3Service s3service = ... // Inject an instance of JetS3t S3Service&lt;br /&gt;File file = ... // File representing download location on disk&lt;br /&gt;S3Bucket bucket // Bucket object (could just be a string)&lt;br /&gt;&lt;br /&gt;Date date = s3service.getCurrentTimeWithOffset()&lt;br /&gt;long secondsSinceEpoch = (date.time / 1000) + 60L&lt;br /&gt;def url = new URL(S3Service.createSignedUrl('GET', bucket.name, key, null, null, s3service.AWSCredentials, secondsSinceEpoch, false, false))&lt;br /&gt;&lt;br /&gt;def cmd = ['curl']&lt;br /&gt;// I break up large downloads so here is an optional byte range.&lt;br /&gt;cmd += ['--range', "${low}-${hi}"] &lt;br /&gt;cmd += ['--show-error']&lt;br /&gt;cmd += ['--connect-timeout', '30']&lt;br /&gt;cmd += ['--retry', '5']&lt;br /&gt;cmd += ['--output', file.absolutePath]&lt;br /&gt;cmd += [url]&lt;br /&gt;&lt;br /&gt;Process p = cmd.execute()&lt;br /&gt;&lt;br /&gt;p.waitFor()&lt;br /&gt;if (p.exitValue() != 0) {&lt;br /&gt; throw new IllegalStateException("Curl process exited with error code ${p.exitValue()}")&lt;br /&gt;}&lt;br /&gt;LOG.info("${file.name} download completed")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;One final note: this will capture a curl process error but not many of the errors that you could experience when working with S3.  For example if the key did not exist, the curl process would succeed but the downloaded file would contain the Amazon error response xml instead of the intended file.  So it is your responsibility to first do a s3service.getObjectDetails(..) to make sure the object exists, then you must check the downloaded content length (and possibly content type) to ensure that you received your object and not an error.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-2340829079107175525?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/2340829079107175525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=2340829079107175525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2340829079107175525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2340829079107175525'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2008/07/amazon-s3-fast-downloads-to-ec2-using.html' title='Amazon S3 Fast downloads to EC2 using Curl'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-4318547228439012545</id><published>2008-07-25T09:17:00.001-07:00</published><updated>2008-07-25T13:14:00.788-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='capsule'/><category scheme='http://www.blogger.com/atom/ns#' term='machine'/><category scheme='http://www.blogger.com/atom/ns#' term='backup'/><category scheme='http://www.blogger.com/atom/ns#' term='time'/><category scheme='http://www.blogger.com/atom/ns#' term='mount'/><category scheme='http://www.blogger.com/atom/ns#' term='failure'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Apple Time Capsule Disk Naming Breaks Backups</title><content type='html'>&lt;div style="float: right; margin-left: 10px; margin-bottom: 10px;"&gt; &lt;a href="http://www.flickr.com/photos/brnboy313/2513845795/" title="photo sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2140/2513845795_dc832f284a_m.jpg" alt="" style="border: 2px solid rgb(0, 0, 0);" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="margin-top: 0px;font-size:0;" &gt;  &lt;a href="http://www.flickr.com/photos/brnboy313/2513845795/"&gt;Apple Time Capsule Ad&lt;/a&gt;&lt;br /&gt;Originally uploaded by &lt;a href="http://www.flickr.com/people/brnboy313/"&gt;Feras Hares&lt;/a&gt;. &lt;/span&gt;&lt;/div&gt;Took me awhile to figure this one out so I'll blog it here to help raise awareness.&lt;br /&gt;&lt;br /&gt;I bought an Apple Time Capsule to add to my home network.  I loved the idea of wireless backups using the cool Time Machine software.  Anyway, I kept having issues where I could see the Time Capsule's disk in the finder but the back ups would fail with a warning about not being able to mount the disk.&lt;br /&gt;&lt;br /&gt;There is a lot of long posts out on the webs but here are two things I tried:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1: Some people were having problems when the Time Capsule disk name was long/contained odd characters&lt;/span&gt;&lt;br /&gt;It appears that the shared disk name (not wireless network name) needs to be fairly short ~25 chars.  This is unfortunate because Apple software tends to default to a long name when you first set up a TC.  (e.g. Joe Owner's Time Capsule).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://discussions.apple.com/thread.jspa?threadID=1434341&amp;amp;tstart=135"&gt;Link to original thread on issue #1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;-- note: this alone did not fix the issue for me but still seemed like a good idea&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2: Delete the last entries in the sparse bundle&lt;/span&gt;&lt;br /&gt;This one seemed to do the trick, got my Time Machine process past the 'processing' stage and into the actual backup (now at 1.2 GB out of 2.2 GB for the current job).  The good thing is all my old backups (except the one day I deleted) still exist.&lt;br /&gt;&lt;br /&gt;Here is a quote and a link to the thread that helped:&lt;br /&gt;&lt;blockquote&gt;I just had the same problem. That error can be caused when Time Machine is attempting to hard link to a previously corrupted backup.&lt;br /&gt;&lt;br /&gt;Try this:&lt;br /&gt;1) Connect to the shared drive from your Mac&lt;br /&gt;2) Mount the .sparsebundle on your Mac&lt;br /&gt;3) Inside the .sparsebundle, expand the folder "Backups.backupsdb"/&lt;your_user_name&gt;&lt;br /&gt;4) Sort the contents by date&lt;br /&gt;5) Delete the link "Latest" and also the most recent incremental backup folder (ie. "2008-06-18-075750")&lt;br /&gt;6) Unmount the .sparsebundle&lt;br /&gt;7) Go into Time Machine Preferences, choose "Change Disk..."&lt;br /&gt;8) Select the shared drive (not the sparsebundle)&lt;br /&gt;9) Click Start Backup. After "Preparing" for a little while, it start backing up again.&lt;br /&gt;10) Click Enter Time Machine when it's done backing up. All of your old backups should be visible (whew!)&lt;br /&gt;&lt;/your_user_name&gt;&lt;/blockquote&gt;&lt;a href="http://sudan.ubuntuforums.com/showthread.php?p=5212655"&gt;Link to original thread on issue #2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;Of course the very first thing you should do is make sure you have the latest OS updates on the machines you are trying to back up.  You should also make sure the hardware flash drivers are up to date on your Time Capsule&lt;br /&gt;&lt;br /&gt;One final detail is that I also have an Airport Express attached to the network to extend the range of wireless reception and to share our printer.  Not sure if this contributed to the issue (probably not)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-4318547228439012545?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/4318547228439012545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=4318547228439012545' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/4318547228439012545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/4318547228439012545'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2008/07/apple-time-capsule-warning.html' title='Apple Time Capsule Disk Naming Breaks Backups'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2140/2513845795_dc832f284a_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-8693698757193925863</id><published>2008-05-19T17:12:00.000-07:00</published><updated>2008-05-19T17:18:51.305-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visual'/><category scheme='http://www.blogger.com/atom/ns#' term='compare'/><category scheme='http://www.blogger.com/atom/ns#' term='beyond'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><category scheme='http://www.blogger.com/atom/ns#' term='diff'/><title type='text'>Beyond Compare for OS X?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_O9auyi9Vy_o/SDIYg-gl9lI/AAAAAAAAAAM/BiaMa1bCAxI/s1600-h/screen.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_O9auyi9Vy_o/SDIYg-gl9lI/AAAAAAAAAAM/BiaMa1bCAxI/s200/screen.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5202247474380928594" /&gt;&lt;/a&gt;&lt;br /&gt;Many developers moving from Windows to OS X will find that one valued application "Beyond Compare" has no mac equivalent.&lt;br /&gt;&lt;br /&gt;Recently a &lt;a href="http://changesapp.com/"&gt;new visual diff application&lt;/a&gt; has come out that works very well (for a 1.0).  It integrates nicely with Textmate and the OS X terminal.  While not as feature-complete and polished as Beyond Compare it does give you the meat &amp; potatoes of what you need - folder and file diffing.&lt;br /&gt;&lt;br /&gt;I encourage you to try it out but remember this is 1.0 software.  For example, see my screenshot of a folder diff.  Notice how the file/folder names are abbreviated even when there is ample room for display.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-8693698757193925863?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/8693698757193925863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=8693698757193925863' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8693698757193925863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8693698757193925863'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2008/05/beyond-compare-for-os-x.html' title='Beyond Compare for OS X?'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_O9auyi9Vy_o/SDIYg-gl9lI/AAAAAAAAAAM/BiaMa1bCAxI/s72-c/screen.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-951510781222570897</id><published>2008-05-02T07:52:00.000-07:00</published><updated>2008-05-02T07:54:23.527-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='spaces'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><category scheme='http://www.blogger.com/atom/ns#' term='Intellij IDEA'/><category scheme='http://www.blogger.com/atom/ns#' term='fixed'/><title type='text'>Intellij IDEA, OS X Leopard Spaces,  Fixed with J2SE 6</title><content type='html'>Looks like the Java 1.6 update finally fixes the Java Swing/Spaces issues that have been so annoying for the last 10 months or so.  Yay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-951510781222570897?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/951510781222570897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=951510781222570897' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/951510781222570897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/951510781222570897'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2008/05/intellij-idea-os-x-leopard-spaces-fixed.html' title='Intellij IDEA, OS X Leopard Spaces,  Fixed with J2SE 6'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-7363025884005235256</id><published>2008-03-31T09:04:00.000-07:00</published><updated>2008-03-31T09:17:17.593-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Intellij IDEA'/><category scheme='http://www.blogger.com/atom/ns#' term='OSX Leopard Spaces solved java'/><title type='text'>Intellij IDEA, OS X Leopard Spaces, pretty good solution</title><content type='html'>As of this writing some Java-based apps still don't work well with OS X 1.5.x (Leopard) Spaces feature.  Specifically, if you are in a different space than where the IDEA window currently resides, command-tabbing to IDEA won't switch you to IDEA's space.  Another side effect is that clicking the IDEA icon in the doc wouldn't bring you to the correct space either.&lt;br /&gt;&lt;br /&gt;I noticed awhile back that if you had two idea projects open in the same space then the problem was solved, Spaces would then work properly with IDEA.  The problem was the pain in the butt factor of having a blank 2nd project open (extra memory and thread resources).  &lt;br /&gt;&lt;br /&gt;I noticed that having any of IDEA's modal dialog windows open (like preferences) also solved the problem.  Today it finally dawned on me to try IDEA's help window and, yes, it worked!   &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution&lt;/span&gt;&lt;br /&gt;Simply open up the IDEA help window and put it behind your working project window.  It won't work if you minimize the help window - it has to be open.  Works great and doesn't suck resources. &lt;br /&gt;&lt;br /&gt;Another solution that works, if you don't mind it, is to float one of the windows (e.g. the debug window).  This works well if you have two monitors.  Simply click the "float" button on any of the windows and move it out of the way.&lt;br /&gt;&lt;br /&gt;Let me know if you have any other ideas or if there is a permanent solution available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-7363025884005235256?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/7363025884005235256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=7363025884005235256' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7363025884005235256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7363025884005235256'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2008/03/intellij-idea-os-x-leopard-spaces.html' title='Intellij IDEA, OS X Leopard Spaces, pretty good solution'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-8097100028915774940</id><published>2007-11-21T11:12:00.000-08:00</published><updated>2007-11-26T09:12:56.712-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='applescript tiling'/><category scheme='http://www.blogger.com/atom/ns#' term='finder'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><category scheme='http://www.blogger.com/atom/ns#' term='terminal'/><category scheme='http://www.blogger.com/atom/ns#' term='window'/><title type='text'>Tile OS X Terminal window to Finder with AppleScript</title><content type='html'>I updated my AppleScript that will tile the terminal window nicely below the frontmost finder window.&lt;br /&gt;&lt;br /&gt;For some reason setting the Terminal window bounds is very buggy.  I resorted to using the deprecated methods {position and size} and have to loop it three times to ensure that it positions correctly.&lt;br /&gt;&lt;br /&gt;I tied this to command-; in my app launcher, &lt;a href="http://docs.blacktree.com/quicksilver/what_is_quicksilver"&gt;QuickSilver&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;tell application "Finder"&lt;br /&gt; --make new Finder window&lt;br /&gt; activate&lt;br /&gt; if not (exists window index 1) then&lt;br /&gt;  make new Finder window&lt;br /&gt; end if&lt;br /&gt; set {x1, y1, x2, y2} to bounds of window index 1&lt;br /&gt;end tell&lt;br /&gt;&lt;br /&gt;tell application "Terminal"&lt;br /&gt; activate&lt;br /&gt; &lt;br /&gt; if (count of windows) is 0 then&lt;br /&gt;  tell application "Terminal" to activate&lt;br /&gt;  tell application "System Events" to tell process "Terminal" to keystroke "t" using command down&lt;br /&gt; end if&lt;br /&gt; &lt;br /&gt; -- For some reason it can take up to 3 times for Terminal to be properly adjusted&lt;br /&gt; set L to {1, 2, 3}&lt;br /&gt; repeat with xxx in L&lt;br /&gt;  set {xx1, yy1, xx2, yy2} to bounds of window index 1&lt;br /&gt;  set position of window index 1 to {x1, y1 + {yy2 - yy1}}&lt;br /&gt;  set size of window index 1 to {x2 - x1, y2 - y1}&lt;br /&gt; end repeat&lt;br /&gt; &lt;br /&gt;end tell&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-8097100028915774940?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/8097100028915774940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=8097100028915774940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8097100028915774940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8097100028915774940'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/11/tile-os-x-terminal-window-to-finder.html' title='Tile OS X Terminal window to Finder with AppleScript'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-3623844094066345811</id><published>2007-11-03T17:12:00.000-07:00</published><updated>2007-11-03T17:24:48.705-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='applescript'/><category scheme='http://www.blogger.com/atom/ns#' term='terminal'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>OS X Leopard - Improved Terminal (almost perfect)</title><content type='html'>Sorry iTerm, my long friend.  I may be giving you up now that Leopard's terminal has tabs and an over-all improved UI.    Terminal starts up fast and is pretty dang stable.  One gripe - "Why can't I name the tabs!"  Ugh, this seems so obvious a feature.   Yeah, you can use AppleScript to set the name of the overall window but that isn't all that helpful when you have multiple tabs open.  Come on, this has got to be a two-day feature (one to implement, one to test).   &lt;br /&gt;&lt;br /&gt;Weird thing is that somewhere in Apple-land there is a small team that is responsible for maintaining Terminal.  And they are programmers so you'd think that they'd make the shell as nice as possible and think of these features on their own.&lt;br /&gt;&lt;br /&gt;Anyway, bravo for the improvements that did make it in but a small "boo" for my couple of wasted hours trying to figure out how to ActionScript custom tab names.  Oh Apple, when you fall short, it really hurts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-3623844094066345811?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/3623844094066345811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=3623844094066345811' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3623844094066345811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3623844094066345811'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/11/os-x-leopard-improved-terminal-almost.html' title='OS X Leopard - Improved Terminal (almost perfect)'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-2360741665556980920</id><published>2007-11-03T16:58:00.000-07:00</published><updated>2007-11-03T17:10:59.214-07:00</updated><title type='text'>OS X Leopard - Incompatibilities</title><content type='html'>I'm an early-upgrader to Leopard.  After a week I'm digging it quite a bit.  This is my small list of bitches in a otherwise pretty nice OS.  I think a lot of the inconsistencies with the Java-based programs has to do with Apple's new GUI rendering.  I don't know much more about it but I'm guessing that it broke (well damaged) a lot of SWT and Swing widgets. Mostly I'm posting these in case somebody else is running into the same issues:  &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Intellij&lt;/b&gt; - Works but now the UI is unstable.  Switching tabs don't always work and a few other creeks and groans.  I use this every day so it is a bit painful.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Popcorn 3&lt;/b&gt; - Bought this last week for my iPhone so I could scale down movies and move them over.  This won't even start up.  Funny thing is Popcorn 1 still works fine.  Roxio has a message on their site that a fix is forthcoming.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;TextMate&lt;/b&gt; - Breaking Input Managers was an issue from day one.  There is a &lt;a href="http://blog.macromates.com/2007/inputmanagers-on-leopard/"&gt;work-around for the "edit in textmate"&lt;/a&gt; bug that works well but it is slightly kludgy. &lt;/li&gt; &lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;I don't entirely blame Apple, seems to me if you are a maker of Apple software you'd do some work with the pre-releases to ensure your software still works with the upgrade.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-2360741665556980920?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/2360741665556980920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=2360741665556980920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2360741665556980920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2360741665556980920'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/11/os-x-leopard-incompatibilities.html' title='OS X Leopard - Incompatibilities'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-7440501602253320802</id><published>2007-11-03T16:48:00.000-07:00</published><updated>2007-11-03T16:56:36.891-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Development'/><category scheme='http://www.blogger.com/atom/ns#' term='13949712720901ForOSX'/><title type='text'>Java 6 on OS X</title><content type='html'>Hey Apple, please be more vocal with your plans for Java.   I love my mac and want to continue using it as my main development machine.  I don't doubt good things are happening - just would like more (good) buzz out there.  I've seen many Java developers be converted to mac (me included - now I own three macs and an iPhone) and then go on to spread the good word.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.sun.com/bblfish/entry/vote_for_java6_on_leopard"&gt;13949712720901ForOSX&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-7440501602253320802?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/7440501602253320802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=7440501602253320802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7440501602253320802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7440501602253320802'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/11/java-6-on-os-x.html' title='Java 6 on OS X'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-9121238929539867052</id><published>2007-09-17T13:00:00.000-07:00</published><updated>2011-12-20T10:53:57.292-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy MarkupBuilder markup builder xml cdata'/><title type='text'>Groovy XML Markup Builder CDATA block</title><content type='html'>This is one of those things that turns out to be easy but takes a bit of time to figure out.&lt;br /&gt;&lt;br /&gt;Using Groovy's builders there are times where you want more control, like when you want to pump out a CDATA block.  This turns out to be quite straight forward:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  out = new StringWriter()&lt;br /&gt;  xml = new groovy.xml.MarkupBuilder(out);&lt;br /&gt;  xml.test_xml {&lt;br /&gt;    normal("Some text in a normal element")&lt;br /&gt;    data('') {&lt;br /&gt;    out.write("&amp;lt;![CDATA[Hello]]&amp;gt;")&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  println out  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically since we have reference to the writer we can dump out anything directly to it.  I'm sure this works with most builders.&lt;br /&gt;&lt;br /&gt;The resulting xml block should look like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;test_xml&amp;gt;&lt;br /&gt;    &amp;lt;normal&amp;gt;Some text in a normal element&amp;lt;/normal&amp;gt;&lt;br /&gt;    &amp;lt;data&amp;gt;&amp;lt;![CDATA[Hello]]&amp;gt;&amp;lt;/data&amp;gt;&lt;br /&gt;  &amp;lt;/test_xml&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;UPDATE EDIT:&lt;br /&gt;&lt;br /&gt;Please note that MarkupBuilder also gives you the special field 'mkp' to do similar actions.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def out = new StringWriter()&lt;br /&gt;def xml = new groovy.xml.MarkupBuilder(out)&lt;br /&gt;&lt;br /&gt;xml.test_xml {&lt;br /&gt;    normal("Some text in a normal element")&lt;br /&gt;    xml.mkp.yieldUnescaped('&amp;lt;data&amp;gt;&amp;lt;![CDATA[Hello]]&amp;gt;&amp;lt;/data&amp;gt;')&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;println out&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Also works and probably is more-correct.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-9121238929539867052?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/9121238929539867052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=9121238929539867052' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/9121238929539867052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/9121238929539867052'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/09/groovy-xml-markup-builder-cdata-block.html' title='Groovy XML Markup Builder CDATA block'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-4569205266529240184</id><published>2007-08-26T22:32:00.000-07:00</published><updated>2007-11-21T11:23:09.530-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tiling'/><category scheme='http://www.blogger.com/atom/ns#' term='iterm'/><category scheme='http://www.blogger.com/atom/ns#' term='finder'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><category scheme='http://www.blogger.com/atom/ns#' term='applescript'/><category scheme='http://www.blogger.com/atom/ns#' term='window'/><title type='text'>OS X Finder iTerm applescript window tiling</title><content type='html'>If you are an OS X developer no doubt you use iTerm.  If you haven't set up your unix environment to synchronize between Finder and OS X you should.  There are a number of examples but here is the ones I used since I'm a zsh fan:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://xanana.ucsc.edu/xtal/iterm_tab_customization.html"&gt;iTerm Terminal Customization&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now the other thing I wanted was to have a quick-key combination to display both the front finder and iTerm windows and position them nicely tiled.  This way I could work in an IDE but have my bare-bones development windows appear in a snap.  Here is my applescript code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;tell application "Finder"&lt;br /&gt; --make new Finder window&lt;br /&gt; activate&lt;br /&gt; if not (exists window index 1) then&lt;br /&gt;  make new Finder window&lt;br /&gt; end if&lt;br /&gt; set {x1, y1, x2, y2} to bounds of window index 1&lt;br /&gt;end tell&lt;br /&gt;&lt;br /&gt;tell application "iTerm"&lt;br /&gt; activate&lt;br /&gt; if not (exists window index 1) then&lt;br /&gt;  set myterm to (make new terminal)&lt;br /&gt;  tell myterm&lt;br /&gt;   launch session "Default Session"&lt;br /&gt;   end tell&lt;br /&gt; end if&lt;br /&gt;&lt;br /&gt; set {xx1, yy1, xx2, yy2} to bounds of window index 1&lt;br /&gt; set bounds of window index 1 to {x1, y2, x2, y2 + (yy2 - yy1)}&lt;br /&gt; activate&lt;br /&gt;end tell&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Store the script in your home/Library/Scripts folder and from there you can assign a hot-key.&lt;br /&gt;&lt;br /&gt;Why don't I just use PathFinder?  Well I own it and used it quite a bit but there are things that just make me angry about it that hopefully they'll fix.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;1. It is a resource hog&lt;br /&gt;2. It doesn't allow me to simply type a path into an input box (actually almost all OS X Finder clones have this issue).  OS X developers seem to like the mouse and drilling down.&lt;br /&gt;3. The UI can be quite busy and some things that should be simple (finding files in the current directory or below for example are a pain in the butt.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Anyway, now that I'm doing quite a bit of development on my mac I'm using QuickSilver, Finder, and iTerm with applescript to glue them together.  Simple.&lt;br /&gt;&lt;br /&gt;What inspired me to dump PathFinder?  This great podcast that showed how much hidden value is in the limited basic Finder application and how a little knowledge can make it much better suited to your workflow.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://macbreaktech.com/9/living-with-the-finder/"&gt;Living with the Finder&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-4569205266529240184?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/4569205266529240184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=4569205266529240184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/4569205266529240184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/4569205266529240184'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/08/os-x-finder-iterm-applescript-window.html' title='OS X Finder iTerm applescript window tiling'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6075501153403397434</id><published>2007-08-02T09:46:00.001-07:00</published><updated>2007-08-02T10:02:45.286-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tomcat spring debugging logging log4j commons-logging'/><title type='text'>Tomat 5.5 Spring 2.0 log4j debugging</title><content type='html'>Had to dig for this one a bit to get spring framework debug to show up.&lt;br /&gt;&lt;h2&gt;Set up logging in Tomcat 5.5&lt;/h2&gt;&lt;br /&gt;Note: CATALINA_HOME is probably the environment variable pointing to your tomcat installation.&lt;br /&gt;* put log4j and commons-logging in ${CATALINA_HOME}/common/lib&lt;br /&gt;* put a basic &lt;code&gt;log4j.properties&lt;/code&gt; file in ${CATALINA_HOME}/common/classes&lt;br /&gt;&lt;br /&gt;for example:&lt;pre&gt;&lt;br /&gt;log4j.rootLogger=DEBUG, stdout&lt;br /&gt;log4j.logger.org.apache=INFO&lt;br /&gt;&lt;br /&gt;log4j.appender.stdout=org.apache.log4j.ConsoleAppender&lt;br /&gt;log4j.appender.stdout.layout=org.apache.log4j.PatternLayout&lt;br /&gt;log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; I turned &lt;code&gt;org.apache&lt;/code&gt; to INFO to ensure I don't get a few miles of digester logging&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; Of course you could add file appenders if you wish - I'm keeping this minimal&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Make sure commons-logging.jar is not in your WEB-INF/lib directory of your web-app.&lt;/b&gt; That seemed to be the thing that switched off the availability for Spring debug logging.  I'm sure there are other ways to get this going but this worked for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6075501153403397434?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6075501153403397434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6075501153403397434' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6075501153403397434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6075501153403397434'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/08/tomat-55-spring-20-log4j-debugging.html' title='Tomat 5.5 Spring 2.0 log4j debugging'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-4214709021287087063</id><published>2007-07-12T11:57:00.000-07:00</published><updated>2007-07-12T12:03:45.545-07:00</updated><title type='text'>TextMate ZSH ZShell</title><content type='html'>TextMate has a bias toward bash and doesn't pick up your environment's path if you are using zsh.&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://macromates.com/textmate/manual/shell_commands"&gt;Shell Commands: Search Path&lt;/a&gt; for details&lt;br /&gt;&lt;br /&gt;I added the following to my .zshrc file to create/update a .profile file whenever I log into zsh&lt;br /&gt;&lt;code&gt;&lt;br /&gt; ECHO PATH=$PATH &gt; .profile&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now bundles like Subversion work as they should :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-4214709021287087063?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/4214709021287087063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=4214709021287087063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/4214709021287087063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/4214709021287087063'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/07/textmate-zsh-zshell.html' title='TextMate ZSH ZShell'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-776742297491871696</id><published>2007-07-12T11:05:00.000-07:00</published><updated>2007-07-12T11:11:30.012-07:00</updated><title type='text'>TextMate Wiki</title><content type='html'>Quick note to advertise an awesome TextMate bundle:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://interconnected.org/home/2007/05/20/plain_text_wiki"&gt;Plain Text Wiki&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Basically it turns TextMate into a plain text file wiki engine.  You can save your notes, serial numbers, whatever in a folder and hyperlink between them.&lt;br /&gt;&lt;br /&gt;Benefits are: &lt;br /&gt;- Completely open format - just plain text files&lt;br /&gt;- Spotlight searchable&lt;br /&gt;&lt;br /&gt;This is exactly what I needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-776742297491871696?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/776742297491871696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=776742297491871696' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/776742297491871696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/776742297491871696'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/07/textmate-wiki.html' title='TextMate Wiki'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-312836166890004457</id><published>2007-04-22T08:28:00.000-07:00</published><updated>2007-04-22T08:49:33.960-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='zsh z-shell unix'/><title type='text'>Z-Shell command completing</title><content type='html'>Alright, I admit it.  I've been using the z-shell for a few years now and have never really dug in beyond what you'd find in bash.  So it finally dawned on me to figure out how to create my own completions.&lt;br /&gt;&lt;br /&gt;Granted, I didn't dig in too far beyond the basics but still it has been extremely handy.  &lt;br /&gt;&lt;br /&gt;For any commonly used command line util get the list of commands:&lt;br /&gt;&lt;code&gt;grails help&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then make a line in your .zshrc (found in your home directory) that maps those commands to the grails keyword:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;compctl -k '(bootstrap bug-report clean compile console create-app create-controller create-domain-class create-job create-plugin create-script create-service create-tag-lib create-test-suite generate-all generate-controller generate-views generate-webtest help init install-dojo install-plugin install-templates package package-plugin package-plugins run-app run-webtest shell test-app upgrade war)' grails&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;compctl can do much more powerful tricks but for me just mapping the given array of words is great.&lt;br /&gt;&lt;br /&gt;Now I can simply type &lt;code&gt;'grails c[tab]'&lt;/code&gt; to list all the commands that start with 'c'&lt;br /&gt;&lt;br /&gt;I've also made a similar array for Subversion:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;compctl -k '(add blame cat checkout cleanup commit copy delete diff export help import info list log merge mkdir move propdel propedit propget proplist propset resolved revert status switch update)' svn&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The best part is if you type &lt;code&gt;'svn help [tab]'&lt;/code&gt; you'll still get the list of keywords so you can easily get detailed help.&lt;br /&gt;&lt;br /&gt;Good stuff.  &lt;br /&gt;&lt;br /&gt;There is a bash plugin available to help program similar completions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-312836166890004457?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/312836166890004457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=312836166890004457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/312836166890004457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/312836166890004457'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/04/z-shell-command-completing.html' title='Z-Shell command completing'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-1461139791092653699</id><published>2007-04-09T05:42:00.000-07:00</published><updated>2007-04-09T06:31:48.922-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java groovy scripting'/><title type='text'>Currently Reading: Groovy In Action</title><content type='html'>I'm about 75% through &lt;a href="http://www.manning.com/koenig/"&gt;"Groovy In Action"&lt;/a&gt; and would recommend it as a great introduction to the power of scripting for Java developers.  I'd also recommend reading "Programming Ruby" for a comparison to a similar, modern scripting language.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Main Thoughts:&lt;/h2&gt;&lt;br /&gt;In the corporate world I've been finding it a small uphill battle convincing talented Java developers that they should take scripting seriously.  It will take a word-of-mouth campaign and probably better tools to get them on board.  I suppose another way would be if someone came out with a "killer-app" written in Groovy.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Less code is less code (Or less code is like gold?)&lt;/h3&gt;&lt;br /&gt;Less code means less code to maintain and also less code to read through to understand what is going on.  A main benefit of a higher level language is that the code you type has more to do with the objective and less to do with the boilerplate required to achieve that objective.&lt;br /&gt;&lt;br /&gt;Put more succinctly: Groovy code is about an order of magnitude less than Java code performing a comparable function.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Less dependencies on Frameworks and Patterns&lt;/h3&gt;&lt;br /&gt;Getting proficient in a scripting language like Groovy will take less time than it takes to learn a new Java framework (JSF, Struts, Hibernate, etc) and may replace the need for one.&lt;br /&gt;&lt;br /&gt;A good example of this is database persistence.  In Java we have JDBC, EJB3, Hibernate, iBatis, Spring JDBC, etc.  Some of these are pretty heavy frameworks that attempt to make database usage easier and less error-prone.  &lt;br /&gt;&lt;br /&gt;When you see an example of database usage from Groovy it really makes you wonder about why you'd want to jump to an external framework.  The argument has often been that heavier frameworks like Hibernate take a lot of the work off your shoulders and reduce the amount of code needed.  I've found that the size of the code just gets transferred to XML configuration and setup.  &lt;br /&gt;&lt;br /&gt;It seems very possible that with a language like Groovy you could have much of this power and security within the language itself, or at least with a much lighter support library.&lt;br /&gt;&lt;br /&gt;If you could write your DAOs in Groovy I know Spring JDBC would be reduced down to a handful of technology-specific helper classes.  Much of this API is resource handling, which is taken care of natively by Groovy's closures.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Design Patterns&lt;/b&gt;&lt;br /&gt;A few years back at a conference, Dave Thomas (Pragmatic Programmers) made the comment that design patterns are a work around for deficiencies in a given programming language.  It took some thinking for this idea to click but it makes so much sense.  What is a design pattern other than simply boilerplate code for a concept not natively supported by the language you are using?&lt;br /&gt;&lt;br /&gt;AOP/Visitor Pattern: Required in Java due to the lack of meta-programming that would allow interception of method calls.&lt;br /&gt;Adaptor Pattern: Required in Java due to the lack of "duck typing" or "mix-ins"&lt;br /&gt;Facade Pattern: Required in Java to hide usage complexity of heavy frameworks/APIs.&lt;br /&gt;&lt;br /&gt;Side note:  If you've done any tech hiring lately you'll notice how many resumes come in with "design patterns" on the technology list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-1461139791092653699?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/1461139791092653699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=1461139791092653699' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/1461139791092653699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/1461139791092653699'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/04/currently-reading-groovy-in-action.html' title='Currently Reading: Groovy In Action'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-3007664681031291237</id><published>2007-04-02T10:53:00.000-07:00</published><updated>2007-04-02T10:57:13.752-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp Java Groovy Ruby'/><title type='text'>Great intro article to the power of LISP</title><content type='html'>I found this great blog entry on why any Java programmer should be interested in learning some LISP.  I'm still a LISP newb but even the little I know makes understanding how to best use scripting languages like Ruby and Groovy better.&lt;br /&gt;&lt;br /&gt;Anyway, take some time to read this:&lt;br /&gt;&lt;a href="http://www.defmacro.org/ramblings/lisp.html"&gt;The Nature of Lisp&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-3007664681031291237?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/3007664681031291237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=3007664681031291237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3007664681031291237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3007664681031291237'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/04/great-intro-article-to-power-of-lisp.html' title='Great intro article to the power of LISP'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-1167249316688787458</id><published>2007-03-16T12:16:00.000-07:00</published><updated>2009-08-24T10:25:10.812-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='macports'/><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>Groovy on OS X and MacPorts</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Update Note: This is still the case with Groovy 1.6.x  and Leopard  the same fix still works.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The default MacPorts install of groovy didn't work out of the box.   When I ran &lt;code&gt;groovy&lt;/code&gt; from the prompt I got a nasty &lt;code&gt;java.lang.SecurityException&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The problem ended up being that my Java CLASSPATH included &lt;code&gt;classes.jar&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The solution ended up clearing out the CLASSPATH system variable altogether before invoking groovy.  You can do this with a command line switch but the easiest way to do it was to edit the &lt;code&gt;startGroovy&lt;/code&gt; file (found in the /bin directory of the groovy installation).  A fast way to find this is using Spotlight&lt;br /&gt;&lt;br /&gt;I simply added &lt;code&gt;CLASSPATH=&lt;/code&gt; as the first thing in the file:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt; ##&lt;br /&gt; ## $Revision: 4298 $&lt;br /&gt; ## $Date: 2006-12-04 02:39:45 +0100 (Mo, 04 Dez 2006) $&lt;br /&gt; ##&lt;br /&gt;&lt;br /&gt; CLASSPATH=&lt;br /&gt;&lt;br /&gt; PROGNAME=`basename "$0"`&lt;br /&gt;...&lt;span style="font-family: Georgia,serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-1167249316688787458?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/1167249316688787458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=1167249316688787458' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/1167249316688787458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/1167249316688787458'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/03/groovy-on-os-x-and-darwinports.html' title='Groovy on OS X and MacPorts'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-951791764958889927</id><published>2007-03-16T10:07:00.000-07:00</published><updated>2007-03-16T10:14:22.725-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Development'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>Groovy Process Piping: Follow-up</title><content type='html'>Thanks to some comments from those a bit more savvy on this topic I'm suggesting the following method from &lt;a href="http://www.blogger.com/profile/04075785767281622678"&gt;charlesanderson&lt;/a&gt;:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;p=['sh','-c','ls -l | sort'].execute()&lt;br /&gt;println p.text&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This is mostly cross-platform (assuming CygWin) and is nicely succinct.&lt;br /&gt;&lt;br /&gt;I like this method over using the Groovy Groosh module as suggested by &lt;a href="http://www.blogger.com/profile/06144534346254158064" rel="nofollow" onclick=""&gt;Yuri Schimke&lt;/a&gt; if only because it doesn't require an import:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def f = gsh.find('.', '-name', '*.java', '-ls');&lt;br /&gt;f.pipeTo(lines);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As always there are many ways to skin the same cat.&lt;br /&gt;&lt;a href="http://www.blogger.com/profile/06144534346254158064"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-951791764958889927?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/951791764958889927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=951791764958889927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/951791764958889927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/951791764958889927'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/03/groovy-process-piping-follow-up.html' title='Groovy Process Piping: Follow-up'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-8004409386765942150</id><published>2007-03-12T07:25:00.000-07:00</published><updated>2007-03-12T10:59:36.527-07:00</updated><title type='text'>Groovy Process Piping</title><content type='html'>I was playing around with using Groovy as a shell scripting language.  While convenient, I found that shelling out to my trusted unix commands is many times faster for file operations than handling them within Groovy.&lt;br /&gt;&lt;p&gt;Creating and executing a process is trivial in groovy:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;p = "ls -l".execute()&lt;br /&gt;println p.text&lt;br /&gt;&lt;/pre&gt;But using pipes or redirection is not allowed:&lt;br /&gt;&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;p = "ls -l | sort".execute()&lt;br /&gt;println p.text&lt;br /&gt;&lt;/pre&gt;For some reason it took me awhile to understand the &lt;code&gt;java.lang.Process&lt;/code&gt; well enough to come up with this script, which contains a helper class for piping one Unix shell command into another.&lt;br /&gt;&lt;pre&gt;def class Pipe {&lt;br /&gt;   private Process p&lt;br /&gt;&lt;br /&gt;   def Pipe(cmd) {&lt;br /&gt;       p = cmd.execute()&lt;br /&gt;       p.out.close()&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   def to(cmd) {&lt;br /&gt;       def p2 = cmd.execute()&lt;br /&gt;       p2.out &lt;&lt; p.in&lt;br /&gt;       p2.out.close()&lt;br /&gt;       p = p2&lt;br /&gt;       this&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   def text() {&lt;br /&gt;       p.text&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def output = new File('output.txt')&lt;br /&gt;output.delete()&lt;br /&gt;&lt;br /&gt;output &lt;&lt; new Pipe("grep -h -e '^.* ERROR .*' input.txt")&lt;br /&gt;   .to("sort")&lt;br /&gt;   .to("tail -n50").text()&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;Note 1:&lt;/b&gt; The Process object is in the standard JDK so with a bit of alteration, one could create the Pipe utility in straight-up Java.  But in regular Java I wonder how often one needs to run a shell command?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note 2:&lt;/b&gt; If you are on Windows and are using Cygwin you'll need to be aware that the Windows "sort" command clobbers the Unix version and is hardly as robust.  You may need to hard code which sort you want to use:&lt;code&gt; "C:\\cygwin\\bin\\sort"&lt;/code&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-8004409386765942150?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/8004409386765942150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=8004409386765942150' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8004409386765942150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8004409386765942150'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/03/groovy-process-piping.html' title='Groovy Process Piping'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-3470143818447395042</id><published>2007-01-25T08:00:00.001-08:00</published><updated>2007-01-25T08:00:16.344-08:00</updated><title type='text'>Posting from Flickr</title><content type='html'>&lt;div style="float: right; margin-left: 10px; margin-bottom: 10px;"&gt; &lt;a href="http://www.flickr.com/photos/devilelephant/252023362/" title="photo sharing"&gt;&lt;img src="http://farm1.static.flickr.com/106/252023362_b0e5d33f7d_m.jpg" alt="" style="border: solid 2px #000000;" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;span style="font-size: 0.9em; margin-top: 0px;"&gt;  &lt;a href="http://www.flickr.com/photos/devilelephant/252023362/"&gt;DSC_0121.JPG&lt;/a&gt;  &lt;br /&gt;  Originally uploaded by &lt;a href="http://www.flickr.com/people/devilelephant/"&gt;devilelephant&lt;/a&gt;. &lt;/span&gt;&lt;/div&gt;Testing the ability to blog my Flickr photos directly.&lt;br clear="all" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-3470143818447395042?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/3470143818447395042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=3470143818447395042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3470143818447395042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/3470143818447395042'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/posting-from-flickr.html' title='Posting from Flickr'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm1.static.flickr.com/106/252023362_b0e5d33f7d_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-427151923452289816</id><published>2007-01-25T07:56:00.001-08:00</published><updated>2007-01-25T07:56:15.606-08:00</updated><title type='text'>Flickr</title><content type='html'>This is a test post from &lt;a href="http://www.flickr.com/r/testpost"&gt;&lt;img alt="flickr" src="http://www.flickr.com/images/flickr_logo_blog.gif" width="41" height="18" border="0" align="absmiddle" /&gt;&lt;/a&gt;, a fancy photo sharing thing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-427151923452289816?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/427151923452289816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=427151923452289816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/427151923452289816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/427151923452289816'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/flickr.html' title='Flickr'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-8251707763578651752</id><published>2007-01-25T07:25:00.000-08:00</published><updated>2007-01-25T07:29:50.368-08:00</updated><title type='text'>Back to Blogger</title><content type='html'>Moved my blog back to Blogger after experimenting with Typo, the Ruby on Rails blogger, on my own server: http://devilelephant.com.&lt;br /&gt;&lt;br /&gt;I'll have to work on getting my view back to what it should be.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Lessons Learned:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Managing your own blog software is a big job.&lt;/li&gt;&lt;li&gt;Typo is hard to upgrade - at least it was for me&lt;/li&gt;&lt;li&gt;The version I was using allowed too many spam messages and talkback links&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Fun AJAX interface is not worth the spam and maintenance. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Kept me from wanting to publish.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-8251707763578651752?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/8251707763578651752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=8251707763578651752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8251707763578651752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8251707763578651752'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/back-to-blogger.html' title='Back to Blogger'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-7031066169803638377</id><published>2007-01-25T07:09:00.000-08:00</published><updated>2007-01-25T07:40:45.819-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Dealing with Crap Code</title><content type='html'>&lt;p&gt;Who doesn’t? Only those who are lucky enough to work on small dedicated teams.&lt;/p&gt;  &lt;p&gt;I think it would be an interesting article to face the fact that crap code and low-level developers are a staple of corporate development. The leaders in our industry whine about this a lot but it is a fact of life and it won’t improve due to economic forces. As long as a corporation can pick up a six-pack of developers from Walmart that will work for 50% of what a talented and experienced developer would work for there will be crap code. It doesn’t matter that statistics show the project will take 10x as long or that maintenance costs will be through the roof. I’ve yet to meet a corporation where those concerns matter to anybody above IT manager (if that).  Long term maintenance is usually not a planning concern and is part of some other department's budget anyway.&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;A sad truth is that the majority of crap code performs similar to quality code so many times it is hard to argue for a decent refactoring.  I’d be interested in figuring out how to use existing frameworks to better localize the crap code to small crap islands (crapplets?). Early n-tier development did this by letting the so-called junior developers do the 5000-line-per-JSP programming while the experienced developers worked on the server. This was great until people started expecting more usable web interfaces.  Now the UI might have as much JavaScript and AJAX magic as the business side of the application.&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;I have yet to see a software process or framework that tackles this issue realistically. They have “roles” but they don’t specify degrees of capability. When 80% of your team thinks threading concerns are when your clothes start to wear out how do you best place them within a project?&lt;/p&gt;  &lt;p&gt;I think it would be fascinating to see a software framework that specifically breaks apart concerns so that you can use your A, B, C, and D developers to the best of their abilities while minimizing the impact of the crap code that the less capable will crank out.&lt;/p&gt;  &lt;p&gt;I don’t want to hear any feedback about how you should just get rid of the junior programmers. They have families, they have to eat, and realistically, if downsized, the more expensive developers will get the boot first. Our industry has to figure out how to best utilize the majority of its C and D-level developers.  We can’t make them all project-managers.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-7031066169803638377?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/7031066169803638377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=7031066169803638377' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7031066169803638377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/7031066169803638377'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/dealing-with-crap-code.html' title='Dealing with Crap Code'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6962966678174355126</id><published>2007-01-25T07:07:00.001-08:00</published><updated>2007-01-25T07:07:55.699-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Development'/><title type='text'>Commenting fields/methods</title><content type='html'>&lt;p&gt;Less comments but more content.&lt;/p&gt;  &lt;p&gt;Along with methods, if a field has to be commented, I’ve found it is usually because it is misnamed.&lt;/p&gt;  &lt;p&gt;&lt;code&gt; // Counter that keeps track of login attempts private int counter; &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Would be better expressed as: &lt;code&gt; private int loginAttemptCounter; &lt;/code&gt;&lt;/p&gt;  &lt;p&gt;It is funny how this simple DRY concept can keep you on the high road of development. Also important is spell-checking and grammar. While a comment shouldn’t be an English thesis paper it should be professionally written. If English is not your strong point have a buddy on the team review your code for errors. Even the best authors lean heavily on editors (the human proof-reading kind not the text-editing kind).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6962966678174355126?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6962966678174355126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6962966678174355126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6962966678174355126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6962966678174355126'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/commenting-fieldsmethods.html' title='Commenting fields/methods'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-2502907179165860949</id><published>2007-01-25T07:05:00.000-08:00</published><updated>2007-01-25T07:06:00.811-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Development'/><title type='text'>EZ Project Management</title><content type='html'>&lt;p&gt;No matter what the chosen process is or how tasks are broken up, every major project I’ve been on has been time blocked:&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;Management decides the new system should be finished by date X.&lt;/li&gt;&lt;li&gt;The analysts and project manager divide the amount of tasks by the number of iterations available before date X.&lt;/li&gt;&lt;li&gt;For each iteration-task-set you divide it evenly amongst your available developers.&lt;/li&gt;&lt;li&gt;You ask your developers for an estimation on their tasks for each iteration.&lt;/li&gt;&lt;li&gt;They respond by taking the number of assigned tasks, divided by the hours available in the iteration.&lt;/li&gt;&lt;li&gt;Some magic happens (scope reduction, overtime, bring in experts to clean up, implement tasks with TODO: statements)&lt;/li&gt;&lt;li&gt;The project finishes on date X.&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;I’ve developed this project management process on a single MS excel sheet. I’m making it available for a cost of $1000 per seat with an annual $10K maintenance charge. Of course I can offer consulting services to customize it to your corporation at a $300/hour bill rate. Do you like curly fonts?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-2502907179165860949?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/2502907179165860949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=2502907179165860949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2502907179165860949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2502907179165860949'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/ez-project-management.html' title='EZ Project Management'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-499815344065216469</id><published>2007-01-25T07:04:00.000-08:00</published><updated>2007-01-25T07:05:09.726-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Development'/><title type='text'>Corporate Code Smells</title><content type='html'>Mostly venting here, how many of these have you seen?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Corporate Code smells:&lt;/span&gt;  &lt;ol&gt;&lt;li&gt;WSAD - There is a reason it isn’t called WHAPPY&lt;/li&gt;&lt;li&gt;Only javadoc is the eclipse message telling you how to change your default javadoc templates&lt;/li&gt;&lt;li&gt;No interfaces at all or an interface for every class&lt;/li&gt;&lt;li&gt;junit.jar exists in the lib directory but no tests to be found &lt;ul&gt;&lt;li&gt;I got this unit test that calls the production database&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;optimized imports? code formatting? we don’t have time in the project plan for that&lt;/li&gt;&lt;li&gt;Sure we use Spring, but we wrap it with our own classes so we can switch it out later &lt;ul&gt;&lt;li&gt;We’ve cached the bean instance returned by Spring to speed things up&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;We added hibernate because we knew we were going to hit the database&lt;/li&gt;&lt;li&gt;Synchronization? Threads? the container takes care of that&lt;/li&gt;&lt;li&gt;Guys, look at this framework I cranked out last night!&lt;/li&gt;&lt;li&gt;With annotations I was able to expose all my classes as web services, you know, for reuse!&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-499815344065216469?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/499815344065216469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=499815344065216469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/499815344065216469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/499815344065216469'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/corporate-code-smells.html' title='Corporate Code Smells'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-2032070957901903653</id><published>2007-01-25T07:03:00.001-08:00</published><updated>2007-01-25T07:40:29.214-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='Darwin'/><title type='text'>Notes on getting Ruby on Rails working on my Powerbook 15</title><content type='html'>&lt;p&gt;Used darwin ports to install ruby and rb-rubygems&lt;/p&gt;  &lt;p&gt;I’m using z-shell so I needed to edit the&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;'~/Library/init/zsh/environment'&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;file to make sure that &lt;/p&gt;  &lt;pre&gt;&lt;code&gt;'/opt/local/bin'&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;was the first folder on my path.  Then I simply did a&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;gem install rake&lt;br /&gt;gem install rails&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;This sounds simple but it only took 5 hours of digging to get right!  &lt;/p&gt;  &lt;p&gt;Come on Apple.  If you are going to include Ruby then make sure you install it correctly.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-2032070957901903653?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/2032070957901903653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=2032070957901903653' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2032070957901903653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2032070957901903653'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/notes-on-getting-ruby-on-rails-working.html' title='Notes on getting Ruby on Rails working on my Powerbook 15'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-387402815255986499</id><published>2007-01-25T07:02:00.001-08:00</published><updated>2007-01-25T07:40:01.756-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Some kids just got to touch that hot stove</title><content type='html'>One of my project’s biggest challenges right now is working around the limitations of a validation “framework”, which is both too restrictive and configuration-heavy. It’s almost always a mistake to attempt to write any kind of “framework” in-house but maybe it is good for this client to get a few of these mistakes under their belts. Some lessons have to be learned the hard way no matter how many books, articles, blogs are written on software development anti-patterns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-387402815255986499?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/387402815255986499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=387402815255986499' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/387402815255986499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/387402815255986499'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/some-kids-just-got-to-touch-that-hot.html' title='Some kids just got to touch that hot stove'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-8411392388576492998</id><published>2007-01-25T07:01:00.000-08:00</published><updated>2007-01-25T07:39:47.554-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>The Dumbening</title><content type='html'>&lt;blockquote&gt;     &lt;p&gt;But then I started to notice something about the Java projects I was involved      in: weak teams and weak programmers will go to great lengths to do      the wrong thing&lt;/p&gt;          &lt;p&gt;Glenn Vanderburg&lt;br /&gt;&lt;a href="http://www.pragmaticprogrammer.com/titles/nfjs06/"&gt;No Fluff Just Stuff - 2006 Anthology&lt;/a&gt;&lt;br /&gt;   Buried Treasure Chapter&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Has the pragmatic press put out a bad book yet?&lt;/p&gt;  &lt;p&gt;I like this quote.  It reflects a lot of my experience with teams lately.  I’d put a different twist on it.&lt;/p&gt;  &lt;p&gt;Here the author was talking about if the “weakest programmers” on the team could be trusted with more powerful language features. An argument may go along the lines of “we need static typing to protect developers from themselves…”.&lt;/p&gt;  &lt;p&gt;A trend I’ve seen in large corporate development is to invest more in smart tools than smart developers. The problem is that smart tools keep developers dumb.&lt;/p&gt;  &lt;p&gt;I’ve been on teams with very green developers and have had two experiences:&lt;/p&gt;  &lt;h2&gt;&lt;span style="font-size:130%;"&gt;Simple Tools: Sophisticated Development&lt;/span&gt;&lt;/h2&gt;  &lt;p&gt;The first is that we set up an ant build that has simple targets. Basically, made it easy for the developer to use whatever IDE they wanted. I just gave them the golden rule that the ant build was king. I also set it up so that server processes kicked off in a console window. Taught them how to use the unix “tail” command on the network servers. &lt;/p&gt;  &lt;p&gt;It turned out that even the weakest developers felt very comfortable with this setup. If something didn’t build they could figure out quickly if it was a code issue, a missing library, or something else. I saw them grow very comfortable with the command line and with Java development in general. In short trusting the developers made them smarter and made the team stronger. I’d see signs of this when the developers would be able to solve complicated problems independently. Because they felt close to the metal they felt comfortable trying to dig out and solve issues themselves. Try a little AOP? Sure. &lt;/p&gt;  &lt;p&gt;The funny thing is that the code was also better. Smaller classes, less code doing more, better javadoc. Pretty much everything that would make a team leader proud.&lt;/p&gt;  &lt;h2&gt;Smart Tools&lt;/h2&gt;  &lt;p&gt;The second experience I’ve had is with a company that felt that tools were the solution. Builds, deploys, servers, were all launched from within an IDE. A right-click generated a web-service, or EJB, or JavaBean. Separate teams were responsible for configuration and deployment and each had their own tools. One example was a tool that would try to inspect the .project file from an Eclipse project setup and use that to generate a build script to be used only by the deployment team. Want to take a guess at how much productivity that sucked away? Here is a hint: The solution was to have the development team check in all generated artifacts so the deploy team’s tool would be easier to use.&lt;/p&gt;  &lt;p&gt;The tools were smart but kept the developers from knowing what was going on behind the scenes. These developers would be able to crank out 100’s of lines of code but would stumble at the basics. They’d be asking why their workstation has red flags while mine didn’t. They’d be lost as to why a deploy didn’t work. Javadoc would be limited to the crap the IDE spewed out. 100s of TODO statements littered the production code. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;In short, smart tools made for dumb programmers.&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Why is this? One theory I have is that programmers want to program - not draw pictures or use someone else’s software. If we wanted fancy tools we would be word processors, graphic artists, CAD professionals, etc. &lt;/p&gt;  &lt;p&gt;If fancy tools were the solution to good software development then industry would have solved the issue long ago. Yes, I love my IDEs. I love code completion when I can get it. Even debuggers, which I feel is the ultimate “smart tool that keeps programmers dumb” come in useful. I’m just saying that the focus should be on what the developers feel would make them most productive. &lt;/p&gt;  &lt;h2&gt;Invest in people first, not tools&lt;/h2&gt;  &lt;p&gt;It is rare to find the developer who does not have potential. Most want to do the best job they can. Most want to learn new things and be considered competent by the team. At the same time, a company that treats its developers like a disposable and replaceable commodity will get developers who live up to that perception. The U.S. military can take 18-year-olds and train them to use million dollar equipment with confidence. That institution knows that setting the bar high will create a team that works well together and as individuals. &lt;/p&gt;  &lt;h2&gt;&lt;span style="font-size:130%;"&gt;&lt;a href="http://www.thesimpsons.com/episode_guide/0917.htm"&gt;The Dumbening&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;p&gt;As always The Simposon’s has a relevant episode. In this one Lisa lives down to her expectations when she thinks she has a Simpson-gene that dooms her to slowly become an idiot.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-8411392388576492998?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/8411392388576492998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=8411392388576492998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8411392388576492998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8411392388576492998'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/dumbening.html' title='The Dumbening'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6996846516520209440</id><published>2007-01-25T07:00:00.001-08:00</published><updated>2007-01-25T07:38:33.534-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='darwinports'/><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='Darwin'/><title type='text'>ze environment is ze file to configure ze shell</title><content type='html'>&lt;p&gt;Bad french aside, here are my notes for configuring the z-shell to find the Darwin Ports version of programs first.&lt;/p&gt;  &lt;p&gt;~/Library/init/zsh&lt;/p&gt;  &lt;p&gt;This path points to where the “environment” is set.&lt;/p&gt;  &lt;p&gt;Edit this file and make sure that your  &lt;code&gt;/opt/local/bin&lt;/code&gt; folder comes first&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;prependPath PATH /usr/local/sbin&lt;br /&gt;prependPath PATH /usr/local/bin&lt;br /&gt;prependPath PATH ~/bin/powerpc-apple-darwin&lt;br /&gt;prependPath PATH ~/bin&lt;br /&gt;prependPath PATH /opt/local/bin&lt;br /&gt;&lt;br /&gt;appendPath PATH /usr/local/mysql/bin&lt;br /&gt;appendPath PATH /usr/bin&lt;br /&gt;appendPath PATH /bin&lt;br /&gt;appendPath PATH /usr/sbin&lt;br /&gt;appendPath PATH /sbino&lt;br /&gt;appendPath PATH /Developer/Tools&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;Note that prependPath and appendPath are functions defined earlier in the “environment” file.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6996846516520209440?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6996846516520209440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6996846516520209440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6996846516520209440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6996846516520209440'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/ze-environment-is-ze-file-to-configure.html' title='ze environment is ze file to configure ze shell'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-2054867207735222056</id><published>2007-01-25T06:59:00.000-08:00</published><updated>2007-01-25T07:38:09.845-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='darwinports'/><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='Darwin'/><title type='text'>Darwin Ports Notes</title><content type='html'>&lt;p&gt;Warning: These notes are mostly plagarized from some other website but I wanted them on mine for easy lookup.,  &lt;/p&gt;  &lt;pre&gt;&lt;code&gt;sudo port selfupdate                   &lt;br /&gt;sudo port upgrade&lt;br /&gt;sudo port install vile&lt;br /&gt;port search 'vile'&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;The search facility uses standard regular expression syntax, so you can also do much more complex searches. Additional Steps: fetch, configure, build, destroot, install&lt;/p&gt;  &lt;p&gt;Once the port has been installed, you may want to delete all the intermediate files that DarwinPorts has created while building the port. To do this, simply use the clean option:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;port clean vile&lt;br /&gt;port clean --all vile&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;h3&gt;Getting Information about a Port&lt;/h3&gt;  &lt;pre&gt;&lt;code&gt;port info vim&lt;br /&gt;port search '.+'&lt;br /&gt;port list&lt;br /&gt;port installed&lt;br /&gt;port installed &lt;portname&gt;&lt;br /&gt;port outdated&lt;br /&gt;port contents vile&lt;br /&gt;&lt;/portname&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;h3&gt;Variants and Dependencies&lt;/h3&gt;  &lt;p&gt;Before you install a port, you may want to check what variations of that port are available to use. Variants provide additional configuration options for a port. To see what variations a port has, use the variants option: port variants vile&lt;/p&gt;  &lt;p&gt;You also may want to see what dependencies a port has. You can use the deps option to check:     port deps vile&lt;/p&gt;  &lt;p&gt;If you want to find out which ports depends on a port you have installed, use:     port dependents gettext&lt;/p&gt;  &lt;p&gt;For more information you should look at the port manpage by entering: man port.     The portindex command&lt;/p&gt;  &lt;p&gt;Most of the time you won’t need to use this command as it is used to build the index of all the available ports, but sometimes the index you have is out of date or innacurate for some reason. When this occurs you will get an error message like ‘port search failed: expected integer but got “PortIndex”’. You can fix problem by moving to the dports directory (/Users/mike/darwinports/dports in our examples) and executing: portindex. This will go through all the available ports in the dport directory and build an index file called PortIndex.&lt;/p&gt;  &lt;h3&gt;Removing ports&lt;/h3&gt;  &lt;p&gt;Ports are removed using the port command described above, simply execute the command:     sudo port uninstall vile&lt;/p&gt;  &lt;h3&gt;Upgrading ports&lt;/h3&gt;  &lt;p&gt;You can check if a port is outdated with the following command:    port outdated gnome&lt;/p&gt;  &lt;p&gt;To check if you have any outdated ports:    port outdated&lt;/p&gt;  &lt;p&gt;To upgrade a port execute:    sudo port upgrade gnome&lt;/p&gt;  &lt;p&gt;This will deactivate the old version and install the new, and also install the newer versions of the dependencies of the port.&lt;/p&gt;  &lt;p&gt;If you would like to upgrade the port, but not the dependencies of the port, you can:    sudo port -n upgrade gnome&lt;/p&gt;  &lt;p&gt;To upgrade all installed ports simply do:    sudo port upgrade installed&lt;/p&gt;  &lt;p&gt;If you dont like that upgrade just deactivates the old version of the port, you can get it to uninstall the old version by using the -u option: sudo port -u upgrade gnome&lt;/p&gt;  &lt;h3&gt;Using force&lt;/h3&gt;  &lt;p&gt;While upgrading you can run into cases when you have to use force (-f). This is especially true if you are upgrading a port that wants to install a file that another port allready has installed, or if you use the -u option to upgrade (and uninstall) a port that could be installed as a dependency. Allways remember to use the -f option with caution. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-2054867207735222056?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/2054867207735222056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=2054867207735222056' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2054867207735222056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/2054867207735222056'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/darwin-ports-notes.html' title='Darwin Ports Notes'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-9192023056492004926</id><published>2007-01-25T06:58:00.000-08:00</published><updated>2007-01-25T07:37:35.490-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails, Plural table names - lame</title><content type='html'>&lt;p&gt;O.K.  I’ve been working with Rails for several weeks now and am loving the ease for cranking out websites.  Good stuff.&lt;/p&gt;  &lt;h1&gt;But…&lt;/h1&gt;  &lt;p&gt;(and that’s a big butt)&lt;/p&gt;  &lt;p&gt;For some insane reason the developers of Rails decided plural table names was a convention worth promoting by having it as the default.&lt;/p&gt;  &lt;p&gt;Most experienced DBAs will tell you that the name of a table should describe what one record in that table would represent. Who would recommend plural table names? Developers seem to like plural names because they equate database tables with Collections (think java.util.List). I guess I come from a more traditional background where I think of tables as set theory.&lt;/p&gt;  &lt;p&gt;Naming guidelines aside there is another reason not to go down this route. Rails then has to be smart enough to parse the plurals for almost every noun in the English dictionary.&lt;/p&gt;  &lt;p&gt;What short-circuited in the developer’s brains? They develop this slick environment and then slap in some hacky idea. I think it is only useful to add to the perceived “wow” factor that the Rails enthusiasts get at conferences. yee-ha!&lt;/p&gt;  &lt;p&gt;Luckily there is a work-around to make Rails work just as nicely with singular table names.&lt;/p&gt;  &lt;p&gt;Thanks to &lt;a href="https://justinram.wordpress.com/2006/04/04/pluralize-table-names-no-thanks/"&gt;this post on justinram.wordpress.com&lt;/a&gt; for providing the answer on how to switch off this really stupid bug in  rails:&lt;/p&gt;  &lt;p&gt;Add the following to the bottom of your config/environment.rb file:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;# Include your application configuration below&lt;br /&gt;ActiveRecord::Base.pluralize_table_names = false&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;h2&gt;Design by convention&lt;/h2&gt;  &lt;p&gt;Final thing that “really grinds my gears” (Family Guy) is that it goes against the grain of “design by convention” that is Rails major contribution to the web space. Why would all my controllers, views, helpers, etc be called Employee and my table name be Employees?&lt;/p&gt;  &lt;p&gt;Why would my code refer to “Sheep” and my table name be “Sheep”.  Well, maybe that wasn’t a good example.&lt;/p&gt;  &lt;p&gt;I guess in the end there is a difference between convention magic: “Hey, all my MVC objects are named the same so I don’t have to configure them - that makes sense” and spooky “under the covers” magic “Hey I magically figured out that your Alumnus class should be related to the Alumni table”&lt;/p&gt;  &lt;p&gt;It is a good thing that Rails has that call to the Dictionary.com web service to get the plural name for every model.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-9192023056492004926?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/9192023056492004926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=9192023056492004926' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/9192023056492004926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/9192023056492004926'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/rails-plural-table-names-lame.html' title='Rails, Plural table names - lame'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-6039926247899197775</id><published>2007-01-25T06:56:00.000-08:00</published><updated>2007-01-25T06:57:07.041-08:00</updated><title type='text'>Be a Better Blogger</title><content type='html'>&lt;p&gt;This week I’ve &lt;a href="http://www.stumbleupon.com/"&gt;stumbled upon&lt;/a&gt; a great web link that I’d like to share with all of us who feel compelled to pound out a few paragraphs a day on a favorite topic:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;a href="http://www.poynter.org/content/content_view.asp?id=61811"&gt; 50 Writing Tips&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Note: if the above link no longer works see my notes at the bottom of this article.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;I haven’t traversed the entire website yet but the “Writing / Editing” section is excellent. I clicked through the “Fifty Writing Tools” articles and they are relevant and entertaining. Entertaining? Yes. Author Roy Peter Clark deserves respect for not only presenting his writing tips clearly but also for sampling across great literature as examples. &lt;/p&gt;  &lt;h3&gt;Dammit Jim, I’m a tech blogger not a Journalism major!&lt;/h3&gt;  &lt;p&gt;Make no bones about it, if you blog or comment frequently in a public space you are a journalist. You don’t need the degree hanging on your office wall but you should try to write like you do. Have you ever stopped reading an article because it was confusing, had spelling or grammar mistakes, or maybe the author’s laptop was missing all of the punctuation keys? We are judged both on our ideas and how well we express them.&lt;/p&gt;  &lt;p&gt;Here’s an exercise: The next time you are reading your favorite board, take a critical look at how the posters express themselves. Which posts do you think give off a sense of authority? Which ones make the authors look juvenile or just plain ignorant?&lt;/p&gt;  &lt;p&gt;How do you want to be perceived?  &lt;/p&gt;  &lt;p&gt;I’m by no means a successful blogger. I get maybe a half-a-person a day to come read my stuff but I do post a lot on other boards. The main purpose for this blog is to practice writing and expressing myself so that if the opportunity comes up to write professionally, I’ll be practiced and in shape. Regardless, I’m trying to write like I have a large base of constant readers. &lt;/p&gt;  &lt;h1&gt;Of Course! Head slap.&lt;/h1&gt;  &lt;p&gt;Ok, here is the bad news. These 50 writing tools are supposedly going to be taken down soon because the author has a book deal and the publisher doesn’t want the content online. I’ve used FlashGot to download all of them locally so I have a chance to go through them. Anyway, I think the site is worth a look and as long as Google stores cached versions.&lt;/p&gt;  &lt;h3&gt;Shh, don’t tell the publisher but…&lt;/h3&gt;  &lt;p&gt;Alright, have you heard of the &lt;a href="http://www.archive.org/web/web.php"&gt;WayBack Machine&lt;/a&gt;. Why, no Mr. Peabody. Well it is an internet archiving site that basically makes snapshots of the internet how it was throughout time. Want to &lt;a href="http://web.archive.org/web/19981202230410/http://www.google.com/"&gt;see what the Google home page looked like eight years ago?&lt;/a&gt;  &lt;/p&gt;  &lt;p&gt;Well if they do take the 50 links off the main site you may be able to still find them &lt;a href="http://web.archive.org/web/20041010110614/www.poynter.org/content/content_view.asp?id=61811"&gt;somewhere else&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-6039926247899197775?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/6039926247899197775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=6039926247899197775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6039926247899197775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/6039926247899197775'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/be-better-blogger.html' title='Be a Better Blogger'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5193038868300749464.post-8612758573475392713</id><published>2007-01-25T06:52:00.000-08:00</published><updated>2007-01-25T07:36:57.214-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='resume'/><category scheme='http://www.blogger.com/atom/ns#' term='tech'/><title type='text'>Tech Resumes</title><content type='html'>Recently, I’ve been helping out interviewing prospective candidates for Java design and architect level positions. You wouldn’t believe how much writing affects your chances of getting an interview. Or maybe I should say you wouldn’t believe how fast your resume gets dragged to the trash can if it is not clear and effective.  &lt;p&gt;Before you apply for your next position &lt;i&gt;get someone you trust to take a critical look at your resume&lt;/i&gt;. Even if you have to shell out money to have someone prepare a professional resume for you it is well worth it. Don’t make the mistake of letting your resume get in the way of your next job. This is especially good advice if English is not your primary language. &lt;/p&gt;  &lt;h3&gt;Does it matter?&lt;/h3&gt;  &lt;p&gt;I think there is the perception out there that for tech resumes all you need is a pile of acronyms and a list of companies you worked for. This isn’t true. &lt;/p&gt;  &lt;h3&gt;Find a standard template that suits your experience&lt;/h3&gt;  &lt;p&gt;There are many good books out there on effective resume writing. There are great examples on the web. You should try to find a template that emphasizes your abilities and can be easily tailored for each position you are applying for. &lt;/p&gt;  &lt;p&gt;If you are new to the job market, you may want to move your education section before your experiences. If you’ve been on the job for awhile you may want to trim down the descriptions of jobs you held 10 years ago.&lt;/p&gt;  &lt;h3&gt;Tech resume essentials&lt;/h3&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;No spelling, grammar, or punctuation errors.  Period.  &lt;/p&gt;  &lt;p&gt;Now that the tech-job market is bouncing back you may be able to get jobs with your sloppy resume. All that means is that you are missing out on better positions.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Tech grid.  &lt;/p&gt;  &lt;p&gt;Yes, you need the dumb little table that tells the HR-bots all of the acronyms that you have under your belt. AJAX, HTML, JAVA, CSS,…. Try to make this grid clear and easy to read for the humans. Try not to include every last technology you’ve come across. Only list the technologies where you consider yourself proficient. Don’t put Ant down if all you’ve done is run an ant build someone else wrote. Don’t put Tomcat down if all you’ve done is write a JSP that someone else delivered to a production box. You don’t have to be an expert on everything you put in your tech grid but you should be experienced to the point where you wouldn’t need training or mentoring on that technology.&lt;/p&gt;  &lt;p&gt;Believe me, if you have a technology on your grid that the client cares about you will be asked about it. If you then say you’ve only had a whiff of experience with it you will not be taken seriously. Remember that a job interview is all about establishing trust. If the client doesn’t trust you they won’t hire you.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Describe how you directly affected the projects you worked on.&lt;/p&gt;  &lt;p&gt;One recent resume I read spent 4 pages advertising for the companies the guy worked at. Entries like: “Ford Motor Company is a large automotive concern whose annual earnings exceed xxx….” Your resume is supposed to be an advertisement for you - not a brochure for others. If anything list the company and the projects you worked on in one or two sentences. What the interviewer wants to know is what did you do at that position? Try to think of specific highlights. How did you positively affect the project’s outcome?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Use metrics Use specific metrics if you can get them.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Compare:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Team leader &lt;/li&gt;&lt;li&gt;Increased performance on data tier&lt;/li&gt;&lt;li&gt;Authored many articles on software process improvement                                                                  &lt;/li&gt;&lt;li&gt;Helped bring in the project under budget.&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;to: &lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Lead team of 20 developers&lt;/li&gt;&lt;li&gt;Helped increase performance on data tier 150%&lt;/li&gt;&lt;li&gt;Wrote over 30 articles on company Wiki regarding software process improvement &lt;/li&gt;&lt;li&gt;Helped my team bring in the project $100K under budget.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5193038868300749464-8612758573475392713?l=devilelephant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devilelephant.blogspot.com/feeds/8612758573475392713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5193038868300749464&amp;postID=8612758573475392713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8612758573475392713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5193038868300749464/posts/default/8612758573475392713'/><link rel='alternate' type='text/html' href='http://devilelephant.blogspot.com/2007/01/tech-resumes.html' title='Tech Resumes'/><author><name>devilelephant</name><uri>http://www.blogger.com/profile/14781597134935171957</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp2.blogger.com/_O9auyi9Vy_o/SIoHeScx_gI/AAAAAAAAAAY/P4EQz46JHJg/S220/Photo+17.jpg'/></author><thr:total>0</thr:total></entry></feed>
