Nelz' Blog

Ruminations on Development


Main | Next page »
Tuesday Jul 08, 2008

Busy Busy Busy

I'm not gonna apologize, but I will let you know why I haven't been posting on this blog in the last month and a half... I have been in the enviable position of having so much actual coding to do that I couldn't do a heck of a lot of reading nor writing about coding.

I have been in the thick of it at Widgetbox, and other than a bit of adjustment time in the other parts of my life I have been rockin' and rollin'!

My biggest accomplishment has been implementing MemCacheD as our distributed cache. I've even submitted a couple of patches to the Spy MemCacheD Java Client. (Dustin, who wrote an maintains that client is a pretty cool cat with loads of talent!)

So.. Yeah... I'm not apologizing. I guess maybe I'm gloating?!?

Wednesday May 14, 2008

GMail has MUTE!

Thanks to my fantastic girlfriend, I now know an awesome trick!

If there is a threaded discussion in GMail that you want to stop hearing from (think flamewars, or a specific discussion you are not interested in on some list that you usually do want to follow...), you can "mute" that discussion. (Supposedly, if you are directly addressed in this thread, it will still deliver the message. S-M-A-R-T!)

There are keyboard nav bindings for it, but I know it is also in the "More Actions" dropdown box at the top of the screen.

What a GREAT feature! It has been saving my attention span immeasurably today!

Thursday May 01, 2008

Quick One - Documentation Answers

As an update to one of my previous posts...

In the Spring documentation, I found the following in "3.9. Glue code and the evil singleton": "... the preferred approach when there is only one web-app (WAR) in the top hierarchy is to simply create one composite Spring IoC container from the multiple XML definition files from each layer"

The documentation was there, but I guess I was using conflicting language when searching for the answer.

Wednesday Apr 30, 2008

Helpful Maven Command: "mvn dependency:tree"

Sometimes you need to peruse the dependencies (and transitive dependencies) within your Maven project. The "mvn site" command generates a pretty nice version of this in HTML. (Example: Jetty Maven Plugin - Depenencies Report.)

Well, the good news is that you don't need to go through the whole "mvn site" generation to find out this information, as the "dependency" plugin can provide this information to you via the command-line.

% mvn dependency:tree

Here is (a part) of the output from one of the projects I'm working on:

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] ------------------------------------------------------------------------
[INFO] Building SomeCompany :: Main Webapp
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree]
[INFO] com.somecompany:somecompany:war:1.0-SNAPSHOT
[INFO] +- com.somecompany:backend:jar:1.0-SNAPSHOT:compile
[INFO] |  +- mysql:mysql-connector-java:jar:5.0.4:runtime
[INFO] |  +- antlr:antlr:jar:2.7.6:compile
[INFO] |  +- commons-codec:commons-codec:jar:1.3:compile
[INFO] |  +- commons-dbcp:commons-dbcp:jar:1.2.1:compile
[INFO] |  |  \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] |  +- commons-httpclient:commons-httpclient:jar:3.0:compile
[INFO] |  |  \- junit:junit:jar:3.8.1:compile
[INFO] |  +- commons-lang:commons-lang:jar:2.3:compile
[INFO] |  +- commons-logging:commons-logging:jar:1.0.4:compile
[INFO] |  +- commons-pool:commons-pool:jar:1.3:compile
[INFO] |  +- dom4j:dom4j:jar:1.6:compile
[INFO] |  +- net.sf.ehcache:ehcache:jar:1.4.0:compile
[INFO] |  |  +- net.sf.jsr107cache:jsr107cache:jar:1.0:compile
[INFO] |  |  \- backport-util-concurrent:backport-util-concurrent:jar:3.1:compile
[INFO] |  +- org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
[INFO] |  |  +- org.hibernate:hibernate:jar:3.2.0.ga:compile
[INFO] |  |  |  +- javax.transaction:jta:jar:1.0.1B:compile
[INFO] |  |  |  +- asm:asm-attrs:jar:1.5.3:compile
[INFO] |  |  |  +- cglib:cglib:jar:2.1_3:compile
[INFO] |  |  |  \- asm:asm:jar:1.5.3:compile
[INFO] |  |  \- javax.persistence:persistence-api:jar:1.0:compile
[INFO] |  +- jdom:jdom:jar:1.0:compile
[INFO] |  +- ognl:ognl:jar:2.6.7:compile
[INFO] |  +- rome:rome:jar:0.9:compile
[INFO] |  +- org.springframework:spring:jar:1.2.7:compile
[INFO] |  +- net.sourceforge.stripes:stripes:jar:1.4.3:compile
[INFO] |  +- velocity:velocity:jar:1.5:compile
[INFO] |  |  \- oro:oro:jar:2.0.8:compile
[INFO] |  +- org.json:json:jar:20070829:compile
[INFO] |  +- org.htmlparser:htmlparser:jar:1.6:compile
[INFO] |  +- javax.mail:mail:jar:1.4:compile
[INFO] |  |  \- javax.activation:activation:jar:1.1:compile
[INFO] |  \- org.safehaus:jug:jar:2.0.0:compile
[INFO] +- javax.servlet:jstl:jar:1.1.2:compile
[INFO] +- taglibs:standard:jar:1.1.2:compile
[INFO] +- javax.servlet:servlet-api:jar:2.5:compile
[INFO] +- com.oreilly.servlet:cos:jar:1.0:compile
[INFO] +- c3p0:c3p0:jar:0.9.1.2:compile
[INFO] +- jaxen:jaxen:jar:1.1-beta-7:compile
[INFO] |  +- xerces:xmlParserAPIs:jar:2.6.2:compile
[INFO] |  +- xerces:xercesImpl:jar:2.6.2:compile
[INFO] |  \- xom:xom:jar:1.0b3:compile
[INFO] |     +- com.ibm.icu:icu4j:jar:2.6.1:compile
[INFO] |     +- xalan:xalan:jar:2.6.0:compile
[INFO] |     \- org.ccil.cowan.tagsoup:tagsoup:jar:0.9.7:compile
[INFO] +- javax.sql:jdbc-stdext:jar:2.0:compile
[INFO] +- org.apache.lucene:lucene-core:jar:1.9.1:compile
[INFO] +- quartz:quartz:jar:1.5.1:compile
[INFO] +- commons-collections:commons-collections:jar:3.2:compile
[INFO] +- org.apache.avalon.logkit:avalon-logkit:jar:2.2.1:compile
[INFO] +- jgroups:jgroups-all:jar:2.6.1:compile
[INFO] \- log4j:log4j:jar:1.2.11:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Wed Apr 30 16:40:42 PDT 2008
[INFO] Final Memory: 12M/508M
[INFO] ------------------------------------------------------------------------

Monday Apr 28, 2008

Leopard and the GIMP

On Friday, I spent the majority of the day banging my head against my laptop.

I wanted to install GIMP (the GNU Image Manipulation Program) to do some image creation for my new Widgetbox widget...

I tried several different ways to install the GIMP (and even GIMPshop), but it kept failing every time I tried to run it.

Eventually, I saw the cautionary warning on the site that hosts pre-built Mac OS X versions of the GIMP.

I will repeat the cautions here: The X11 package you can find on a OS X 10.5.0 install disk is too old to run GIMP (it will crash), and it can't be updated through software update.

There appears to be several different ways to address the problem, but the one that worked for me was to download and install the latest version of the XQuartz project.

Wednesday Apr 23, 2008

Blogging Works For Me!

I understand how a lot of people are opposed to personal blogging as an exercise in navel-gazing. But I am here to tell you that it works for me!

I have never been a journaler, because it also felt very navel-gazey to me. Writing on paper would be futile as I would lose the paper. "Engineers notebooks" are close, but when I tried that path, I felt I need automated searching capabilities to find things.

In regards to an online blog, with the possibility of my musings helping others I feel much more motivated to actually post. And, the secondary benefit is that I have an online repository of my own ideas. No less than 3 times in the last week have I been able to refer to one of my own previous blog posts as an aid for either work or community.

Blogging can be bad, no doubt about it... But, in some instances it can be really beneficial!

Tuesday Apr 22, 2008

Self Allowances as Code Smell

Lately, I've been noticing a theme in development. Sometimes, an organization will grab hold of an edge-case truism and run with it.

I think this is a big vector for code smell... If you give yourself a pass to violate good programming practices too early you are probably doing yourself a disservice, and you will probably suffer the headaches from it later.

According to Wikipedia, "an edge case is a problem or situation that occurs only at an extreme (maximum or minimum) operating parameter". If you are going to allow yourself to utilize an edge-case strategy, then you should make sure you are really seeing the 'extreme operating parameters'. If you end up using this edge-case strategy many times in your code, maybe you need to reevaluate your definition of 'extreme'.

(And, for those of you wondering, the statement that got me thinking along these lines is this: "sometimes you need to denormalize your data...")

Monday Apr 21, 2008

Live Code

First, let me make the following announcement:

Widgetbox.com's new homepage was released today!

Now, I have a confession to make... I realized that this is the first time in my (paid) career that I've had any code of mine out and in the wild for public consumption.

I've had side project code get released (like here or here or here), but never anything that I've worked on 'professionally'.

My pre-Web work at Eclipse Inc was a large application that you interacted with via (mostly) dumb terminals, with a whopping 24 X 80 character resolution. It was a hard-goods distribution application, which my grandmother would have no hope of ever accessing.

At ICAT, it was all web applications though they weren't for public consumption, just for internal or partner usage.

At PlanetOut/Gay.com we were rewriting Gay.com. My code there will be released into the wild soon, but it isn't scheduled to happen for at least another month or two.

So, this leaves Widgetbox. I got to write some of the code facilitating the different modules on the home page, such as the "Hidden Gems" or "New and Notable" or "Hottest Widgets".

It's pretty cool, because I think my Widgetbox stuff could pass the "Grandmother Test".

Ruffled My Feathers

Vendor Relations

The other day we met with a vendor who was proposing that we use their paradigm-shifted product. I'm okay with the vendor in general, and actually I kind of like their product.

But, I asked some questions that the Sales dude cast as tactical rather than strategic, and basically said I shouldn't worry about the tactical issues. After chewing on the conversation a bit, I'm gonna say "No!" Yeah, so my questions were tactical, but if the developers can't easily simulate a scaled-down version of the production environment, then your product actually does lose value to me. (In the end though, their product can easily scale down.)

Now, allow me to vent on another tangent... Hey "Sales Guys", I do not need you. Gimme a "Sales Engineer" any day... (One that is actually technical, BTW...) I can talk to those people. However, when a "Sales Guy" comes in with hyper-tanned leathery skin and mega-sun-bleached hair, talkin' all smarmy-like... I just wanna kick them in the shins and tell them to get out of my face. In my experience, "Sales Guys" like this are nothing but liars and over-promisers, to both the customers and to the actual engineers he is representing.

Framework Support

I've had a question posted to the Spring Framework Support Forums for a couple of weeks now. Yet, no authoritative member has responded... The only traffic at this point is myself and another guy who is also trying to figure out the same stuff.

I think I came up with a viable solution and posted it on that thread... But, it will (probably) be a couple of months before I get to experiment with it directly at work... But when I do, I'll try to remember to post my findings.

Wednesday Apr 16, 2008

History Meme

I found a new meme spreading amongst the technorati... The "history" meme. (See previous examples here, here, and here.)

Basically, you run a script to show what commands you frequently use.

Here's my output:

$ history|awk '{a[$2]++} END{for(i in a){printf "%5d\t%s \n",a[i],i}}'|sort -rn|head
  102   svn 
  100   ls 
   74   cd 
   49   wget 
   31   ruby 
   28   rm 
   13   exit 
   10   gem 
    9   which 
    8   mv 

What is yours?