somewhat daily mutterings

/Programming Creating an IntelliJ Module Dependency Graph with Only Unix tools, Dot, and GraphViz

Every so often I like to generate a dependency graph of the modules in our system. Historically, I've used an IntelliJ plug-in to do it. The plug-in generated a "graphml" file that could be displayed using yEd. All-in-all a pretty good approach.

So, yesterday I went to do just that. However, the plug-in apparently doesn't work in IntelliJ 9.x. Bummer. What to do? Well, I know that IntelliJ module definitions are stored in .iml files. I also know these files are XML. So, I popped open one of our .imls and discovered that module dependencies are recorded as follows:

<orderEntry type="module" module-name="bridging" />
I thought to myself, "Self, seems like I should be able to process our .iml files with some Unix utilities and generate a "dot" file that can be rendered by GraphViz. I'll bet I can do that in a half-hour." I won the bet.

Here is the script I hacked out in about 20 minutes. I first did it at the command line, then canned it in a .sh file.

  echo 'digraph g {'
  echo 'graph [ ratio="1.0" ];'
  echo 'node [ shape="rectangle", style="bold", width="5.0", height="2.0", fontsize="42" ];'

  # Find all the module files beneath this directory
  # Process only orderEntry elements of those files
  # Get rid of XML stuff
  # Extract module name from file name
  # Unquote to get tokens accessible to awk
  # Output node dependencies
  # Strip out uninteresting nodes (could be done earlier, but prettier at the bottom).
  find . -name '*.iml' \
      | xargs grep -H 'orderEntry.*module' \
      | sort \
      | sed 's///g' \
      | sed 's/\..*\///g;s/\.iml://g' \
      | sed 's/"/ /g;' \
      | awk '{print $1, "->", $6, ";"}' \
      | grep -v 'webapp' \
      | grep -v 'devTools' \
      | grep -v 'common' \
  echo '}'

Note: I make no claims about the elegance of the script!

The above script processes all the .iml files in our project, extracts the module dependency lines, does some sed replacements to get useable tokens, and awk to print out the actual dependency lines. If you open the file in GraphViz, it generates a diagram something like this:

This, my friends, is why all the cool kids run Unix-like OSs (Mac OS X in my case).

Posted: Wed Sep 29 20:29:11 -0700 2010

/Programming Programming in Color

Whoa. Just Whoa.

This is source code

Mark Chu-Carrol has just officially blown my mind.

Posted: Tue Nov 07 09:12:44 -0800 2006

/Programming/Ruby My First Paying Rails Gig

OK, my first ever Ruby on Rails gig is also a paying gig. I can't go into too much detail at the moment, but I just started moonlighting on a Rails project for a friend of mine. It's a fairly small site, basically to provide some information about his consulting practice and to give access to his articles and scheduled appearances. As such, it is pretty much the perfect starter Rails project.

My first step was to generate a rails project and "pour" his prototype into the public directories. Having done that, I can start the rails server and look at the content as served by rails. This will give me something to refer to while I move bits of the static content over into view implementations.

Next steps are to get the code into a repository at the hosting service, so we can start collaborating on the app. I'll post more details here, as appropriate, as the project proceeds.

Posted: Tue Feb 07 12:40:44 -0800 2006

/Programming/Ruby Rails Studio Denver, Day Three

Day three was kind of divided into two parts: completion of Rails basics before lunch, then a grab-bag of more advanced topics after:

  • sending email
  • controller hooks and filters
  • web services
  • security
  • deployment issues
  • deployment using SwitchTower

Lunch itself was combined with the much-needed exercise of building a small app from scratch. Of course, my bud Bill (who came up from Dallas) and I burned up most of the allotted time cutting up in the back of the room over our lunch, and thus had only about 40 minutes to build the app. We did so by pairing-by-sharing, whereby he shared his hard drive and we worked on separate parts of the very same project. It worked out OK, but our app didn't turn out to be very sophisticated.

I really hope that Dave and Mike plan on creating an advanced RoR class, because in all, this class was not as deep as I'd have liked. I kind of felt as though I could have gotten nearly as much from going through Dave's excellent RoR book and following along with the Depot project on my machine. This is not to say that the class was bad - I know some folks appreciated it at the level it provided, and as I said before, you can't please everybody. However, I do think a class that focuses on actually building an app from start to finish, with the class perhaps dividing into teams, would be a big success. Perhaps the format could be: mornings spent covering the previous day's foibles, then some RoR feature training, then the entire afternoon spent applying the training.

That said, the class was a great way for me to immerse myself in RoR training to a degree which I probably would not have done on my own. I paid for the class myself (and used vacation time), and thus was quite compelled to take an interest. It was also a great networking opportunity, and having Bill in for a visit was fun, too.

Posted: Sun Jan 22 08:51:15 -0800 2006

/Programming/Ruby Rails Studio Denver, Day Two

We dug deeper into Rails today and covered a huge range of topics:

  • link generation
  • session management
  • ActiveRecord relationships
  • Ajax
  • rails form binding
  • web "components"

The format today was mostly presentation, with few exercises. This was a double-edged sword - a lot of information was provided (much more so than day one), but there was little opportunity to experiment with what was presented.

After class, a group of eight of us headed into downtown for Indian food. It was a bit of a wild goose chase finding the restaurant, but then we enjoyed great Indian food and beer. Aside from the usual geeking out, we were regaled with entertaining tales by an French expatriate attendee named Fernand.

Posted: Sun Jan 22 08:26:02 -0800 2006

/Programming/Ruby Rails Studio Denver, Day One

Just a very short entry, because that's all I have time for. The class is composed of about 50 attendees, from all sorts of development backgrounds. In terms of content, Dave and Mike first did a very short Rails history, then spent the morning on a Ruby review. Even though I've been coding in Ruby (inconsistently) for a few years, I picked up a couple of new things. The afternoon was spent getting up to speed on Rails basics, digging shallowly into ActiveRecord and static and dynamic scaffolding. Probably the most interesting and useful topic was that of migrations, which allow you to "version" changes to the database schema (and data!) as you progress through a project.

In all, the day moved a bit slow for me, but I'm sure there were folks for whom it was just right. You can't please everybody.

After class, a few of us headed into downtown Denver for dinner at P.F. Chang's, and had a good time geeking out over beers, lettuce-wraps, and other sodium-filled goods.

Posted: Sun Jan 22 08:22:34 -0800 2006

/Programming Strangling Legacy Code Roundtable

I'm hosting a roundtable in support of my article "Stangling Legacy Code", which appears in this month's Better Software magazine. The roundtable runs from Oct 10 through Nov 10. If this topic interests you, please stop in and add your insights.

Posted: Thu Oct 06 07:25:28 -0700 2005

/Programming An Interesting Reference to The Costanza Principle

In my Strangling Legacy Code presentation and article (Better Software, Oct 2005), I coined the term: "The Costanza Principle" (TCP). TCP It refers to the Seinfeld character George Costanza, and is basically a funny way of saying "learn from past mistakes". Anyway, I was doing some "strangling" research, and came across this interesting reference to TCP on Villane Bardak's site. Although he's a Java developer, the post has nothing in particular to do with software:

"Secondly, Seinfeld is way above Not Too Shabby. You can simply tell that from the various contexts it is often referenced in. The jokes are often quite unique, compared to other sit-coms. Or even if they aren't, they sure fooled me. For example, google for "Costanza principle" and download the powerpoint file "Strangling Legacy Code", then search for "Costanza" in the file again. It shows how a joke from one the episodes can apply to solving a real-life software engineering problem."


Correction: I thought I had uniquely coined the term for my presentation, but when I run the Google search he suggests, I come up with a million (OK, actually 109) similar "coinages". Bummer. Well, I can honestly say that I independently coined it, but not that it was a unique.

Posted: Fri Sep 30 07:10:36 -0700 2005

/Programming/Java A Napkin-sketch Look and Feel

In a stroke of pure genius, Ken Arnold introduces his "napkin look and feel". The purpose behind it is to keep stakeholders reviewing the design from considering it "done". I think this has two dimensions: 1) it makes it seem easier to change, and 2) it doesn't look as though it can be shipped.

If only we were developing a Swing app at my shop, we'd definitely be using this technique. Instead, we build static HTML prototypes that our UI guy always polishes to perfection (even though I've repeatedly mentioned that we should not try to make it look to pretty). Maybe we should attach an "ugly" stylesheet to the prototype, although we could never get the same great hand-drawn effect.

Posted: Fri Sep 30 06:50:34 -0700 2005

/Programming/Ruby Watching Ruby on Rails Metastasize...

... and I mean that in a good way. One of my favorite examples is how Justin Gehtland has moved from a RoR experimenter flush with early success to a full-on proselyte. It's been interesting reading his accounts of RoR experimentation and seeing the transformation in progress. Of course, he's a consultant, so it makes very good sense for Relevance LLC to jump on the RoR bandwagon with both feet and a bag of chips (mixed metaphor very intended) but let's not get too cynical (it's hard, but I try).

Thanks for the posts, Justin. I'm only a little envious.

Posted: Sat Aug 27 08:17:16 -0700 2005

/Programming/Projects/Gemcast Gemcast 0.1.0 Available

I've done some major refactorings in gemcast, the Ruby-based weblog engine that runs this site. I've rewritten some pieces, and added new features here and there.

The two main new features are a "Top" entry for the Categories sidebar, and the ability to display a single weblog entry, like this. This latter feature I'll be able to use for "real" permalinks (although they'll only be permanent if I don't move or rename my blog entries), rather than the anchor hack that I was using before (and that stopped working as soon as the entry scrolled off the bottom of the blog). As a side-effect of the latter, I've also started down the road of making gemcast's URLs compatible with blosxom's URLs, which is reasonable, given that gemcast is a ruby-based knock-off of blosxom.

Read more about gemcast here.

Download gemcast 0.1.0

Posted: Sun Aug 14 17:25:27 -0700 2005

/Programming OSCON 2005

I was in Portland last week for the O'Reilly Open Source Convention. It was a great time, as was the larger, 1+ week, vacation for myself and MB that wrapped around the convention (more on that in a different post).

I mostly concentrated on the ruby track, since I paid the entry fee myself, and by God, I'm gonna get as much ruby as possible! One more thing on ruby before I shut up about it - it definitely had the buzz at OSCON. No doubt about it. Much of it was fueled by Ruby on Rails, which is a shame (no reflection on Rails, per se). Ruby is good enough that it should be able to stand on its own, and Rails is just another good thing about it.

Anyway, I've posted some photos from the convention on (at the moment you can see a random photo directly on my flickr sidebar).

Posted: Sun Aug 07 21:36:23 -0700 2005

/Programming/Java Note to Self: Read this Article

Cameron Purdy on Caching (via The Server Side).

Posted: Mon Feb 14 08:10:52 -0800 2005

/Programming/Java Bug in Hibernate UserType Example

In Gavin King's excellent book Hibernate in Action, there lurks an insidious bug. If you follow his custom UserType implementation example on page 203, you're in for big trouble and lengthy debugging sessions. Here's the example

public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) 
        throws HibernateException, SQLException {

    if (resultSet.wasNull()) return null;    // <------- BUG!!

    BigDecimal value = resultSet.getBigDecimal(names[0]);
    return DataUtils.toPercentage(value);

The problem with the above code is that the wasNull() call is not preceded by a get*() call. In our particular circumstance, once wasNull() returned true (due to a null value in a given column), it kept returning true for every column that was mapped using the UserType. This, of course, resulted in the subsequent fields of this type being given null values, even if the column did not contain a null value.

Do I need to say that this is a very subtle bug that pops out in odd places, and is extremely difficult to find? I spent hours with log messages and the debugger. The right way to do it is as follows.

public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) 
        throws HibernateException, SQLException {

    String name = resultSet.getString(names[0]);  // <----- You GOTTA do this!
    if (resultSet.wasNull()) return null;

    BigDecimal value = resultSet.getBigDecimal(names[0]);
    return DataUtils.toPercentage(value);

Posted: Fri Jan 28 10:53:52 -0800 2005

Thanks for visiting! Send comments to Mike Thomas.