Nelz's Blog

28 June 2009

The New Nelz.net

Filed under: General — nelz9999 @ 13:12

Welcome to the new and improved Nelz.net!

Background

I started this blog way back in the beginning of 2007. At the time, I wanted more than just a blog host, I wanted a host where I could deploy other Java webapps if I felt the need. (For other side projects, y’know.) Following the lead of Matt Raible, I chose KGBInternet to host a Roller (which wasn’t then, but is now an Apache project) blog instance. Keith, the proprietor of KGBInternet, is incredibly responsive and I’d have to say that his service was a great $20/month host where you get full command-line access and control over your JVM/Tomcat instances.

A couple of months ago, I decided to critically look how I use my different online providers.

I had been maintaining a cheap, $5/month GeekISP account for personal data SVN hosting/backup. Since most of my projects are Open Source (and usually hosted on Google Code), I realized I wasn’t really using my account, so I dropped it.

And when I critically looked at my usage of KGBInternet, I realized that I was only using it for maintaining my blog. That’s $240 (Candian) bucks per year for blog hosting, which could be done for much less by another provider. So, I decided to drop that account.

Getting Data Out Of Roller

The biggest problem I had was trying to get my blog content out of Roller. There is no “Export” functionality, which frustrated me to no end. I found a posts with a tutorial on how to export directly from the database, but that wouldn’t work from me because 1) I didn’t want to go through a PHP export process, and 2) my db entries are all in JSPWiki markup (via the Roller JSPWiki plugin). I found another post showing how to get my data out using Roller templates, but that wasn’t going to specifically work for me, since I wasn’t going to be hosting my own WordPress install. However, the concept of using the built-in Roller template capabilities had a bunch of potential.

At this point, I wasn’t yet sure if I was going to end up using WordPress.com or Blogger. My investigations proved that Blogger only likes to import/export in their own format, for which I could find no documentation. WordPress however has several import capabilities, so I figured I’d target WordPress, and maybe use some of the community WordPress -> Blogger converters if I needed to move my stuff over to there.

WordPress has its own WordPress eXtended RSS (WXR) syntax, but it’s not easy to get a definitive format information. WordPress will import from a MoveableType export file, which is actually very well-documented. This is what basically decided me on moving to WordPress, at least for the time being…

By referring to both the MoveableType documentation and the Roller templating guide, I was able to create the following template:

 1  #set($pager = $model.getWeblogEntriesPager())
 2  #set($map = $pager.getEntries())
 3  #foreach( $day in $map.keySet())
 4  #set($entries = $map.get($day))
 5  #foreach( $entry in $entries )
 6  TITLE: $entry.title
 7  AUTHOR: nelz9999
 8  DATE: $utils.formatDate($entry.pubTime, "MM/dd/yyyy HH:mm:ss")
 9  CATEGORY: $entry.category.name
 10  -----
 11  BODY:
 12  $entry.transformedText
 13  #foreach( $comment in $entry.comments )
 14  -----
 15  COMMENT:
 16  #if ("$comment.name" != "")
 17  AUTHOR: $comment.name
 18  #end
 19  DATE: $utils.formatDate($comment.postTime, "MM/dd/yyyy HH:mm:ss")
 20  #if ("$comment.email" != "")
 21  EMAIL: $comment.email
 22  #end
 23  #if ("$comment.url" != "")
 24  URL: $comment.url
 25  #end
 26  $comment.content
 27  -----
 28  #end        
 29  --------
 30  #end
 31  #end

One of the keys in the above template is Line #12. Instead of using “$entry.text”, I use “$entry.transformedText”, which applies all the JSPWiki formatting. (And, if you’re copy/pasting this template, be sure to update the “AUTHOR:” tag on Line #7 to something appropriate for you…) Keep in mind that this gets you one page of (published, not draft) content at a time, as defined by the “Number of entries to display on weblog” parameter in the Preferences -> Settings tab. You get to later pages of data by appending “?page=X” (0 being the default) to the URL: “http://nelz.net/roller/nelz/page/moveabletype.tmpl?page=1″.

It is then a simple matter of doing a “wget” for each page: “wget http://nelz.net/roller/nelz/page/moveabletype.tmpl?page=1 -O page1.txt”. If you have lots of posts, I’d recommend upping your entries/page setting, so you have less individual files to manage, but also beware of your file sizes getting too big… I left my entries/page setting at 10, and I ended up managing 14 files. Had I set it to 50 entries/page, it would have been only 3 files.

But, now you’ve got most of your content (not images and stuff tho) in a portable format!

Getting Data Into WordPress

After creating my WordPress.com account, it was pretty simple to get the data in, via the Tools -> Import menu. Now, I had 138 posts in Draft status. I tried using the bulk edit -> publish tool, but for some reason that wasn’t working for me. I published a couple by hand, but then I remembered back to something Neil Ford said at a conference I attended: “our computers get together and laugh at us at night because we keep doing their (repetitive task) jobs for them…” Well, I’ll be damned if I let my computer laugh at me!!

So, I popped open SeleniumIDE, and created a quick little automation to approve all the drafts in my queue, a single iteration of which looks like this:

<tr>
 <td>open</td>
 <td>/wp-admin/edit.php?post_status=draft</td>
 <td></td>
</tr>
<tr>
 <td>click</td>
 <td>link=Quick Edit</td>
 <td></td>
</tr>
<tr>
 <td>select</td>
 <td>_status</td>
 <td>label=Published</td>
</tr>
<tr>
 <td>click</td>
 <td>link=Update Post</td>
 <td></td>
</tr>
<tr>
 <td>waitForText</td>
 <td>//img[@alt='More stats']</td>
 <td></td>
</tr>

This worked swimmingly, and in 30 minutes or so, I published nearly 140 posts “by hand”. :-D

Getting to know Wordrpress

Things that I like about WordPress:

  • It is a much better interface than Roller
  • “Pages”. I also use my blog as a place to keep an online version of my resume, and Pages allow me to exactly do that without having to use a ‘regular’ blog post that I update over time.
  • WordPress automagically figures out how to map the old Roller URLs to the new ones. I was getting quite a few links to some of my recent posts, and I really happy that the links floating around the web-o-sphere will still work. (E.g. “http://nelz.net/roller/nelz/entry/velocity_conference_recap” ends up on the page “http://nelz.net/2009/06/25/velocity-conference-recap/“.)
  • Setting up my own domain was absolutely painless.

Things that I haven’t yet decided on:

  • You can’t use Google Analytics on a WordPress.com blog, but they do provide some of their own stats (and there are several other options as well). I haven’t yet decided if it’s better to have the stats easily available in my blog admin, or if I’d have preferred to keep all my analytics stuff together in Google.
  • I haven’t yet purchase the $30/yr no ads upgrade. I haven’t seen any ads on my site as it is, so I’m not sure if I will actually need it?
  • No specific control over robots.txt. Whereas I want 99% of my blog public, I want to prohibit Google from picking up my resume, ‘cuz I kinda hate cold-calls from recruiters (but maybe I’m just being silly).

To Do

  • Some of the formatting (especially on the preformatted code sections) got lost in the migration… I’ll try to go back to the most used ones to reformat.
  • I gotta update that resume of mine.
  • Once I’ve been up on WordPress for a week or two, I’ll actually cancel my account with KGBInternet.

25 June 2009

Velocity Conference Recap

Filed under: General — nelz9999 @ 00:05

These are the notes I collected (and found interesting) during my day at the Velocity Conference.

General Themes

  • I had never heard of it before, but almost every single presenter referenced Ganglia as a de-facto monitoring system.
  • It got presented a bunch of different ways, but basically all the big sites that presented stuff today all use on and off (or dial-able) configurations for features. This is not just for release-time of new features, but this can also help them manage their capacity if something is going wrong.
  • Many of these talks are available online: http://velocityconference.blip.tv/

“Image Weight Loss Clinic” at Ignite Velocity

  • Stop using GIFs. Use PNGs.
  • Use data strippers/filters on JPGs. There is a lot of ‘extra’ data included in JPG that aren’t necessary.
  • There are bunches of PNG optimizers out there. We should use at least one, if not all of them. (The suggestion was to build a serial pipeline for them.)
  • Using the Velocity page as an example, the presenter was able to reduce the page weight by 30% following these suggestions.

The User and Business Impact of Server Delays, Additional Bytes, and HTTP Chunking in Web Search

  • A lot of people loved the empirical data showing that slower sites cost you users, even for differences as small as 200ms. Brady Forrest wrote up a great digestion of this talk: “Bing and Google Agree: Slow Pages Lose Users
  • The technique that I pulled outta the whole deal is to use HTTP 1.1 Chunked data. This enables a site to deliver the easy-to-compute stuff first (static header?), and the harder-to-compute stuff later.

Fixing Twitter: Improving the Performance and Scalability of the World’s Most Popular Micro-blogging Site

  • Uses NTT America managed hosting
  • Put Google Analytics on 503 (Fail Whale) and 500 (Robot) pages. Use Google Analytics for failure metrics.
  • Configuration Management: Do it ASAP, early & often, ‘cuz you’re gonna need it eventually
  • Even their Ops stuff is checked into SVN, and they require code reviews on all their stuff, enforced by SVN pre-commit hooks and using Review Board
  • Send emails (or ANYTHING ELSE POSSIBLE) asynchronously
  • They recommend using “mkill“, which monitors for long-running queries and kills them, before the queries kill your site.
  • Instrument EVERYTHING for timing/performance.

2 Years Later, Loving and Hating the Cloud

  • Presented by an engineer from Picnik. They run a hybrid (part-cloud, part managed) site.
  • Queues scale nicely in AWS. (I.e. if you are falling behind processing your queue, it is nigh trivial to just bring up another box to deal with the queue.
  • In the cloud, you can plan for your average usage, and scale up/down as needed easily. (You don’t need to keep the 6th box at 1% utilization up, do you?)
  • Buy hardware in batches, it gives you flexibility. No scrambling if you need a new box when there are extras around. Also waiting for good deals on price fluctuations on hardware.
  • If you don’t have a good deletion plan on S3, it can end up costing you $$
  • Being in the cloud enables you to ignore the S3 space problem, operationally at least, until it is too expensive (leaving you opportunity to work on other low-hanging fruit)
  • Whereas you can get some nice SLA’s when dealing within your own network, latency should be treated as a complete unknown in the cloud.
  • Be prepared for some difficult and juicy debugging when using the cloud.

Page Speed

  • Twitter is a fantastic feedback mechanism, more so than Google Groups / wikis / forums (me: lower barrier for commentary?)
  • Browser Tool like Firebug
  • Someone (on Twitter?) made a very apt comment that it’s kinda sad to see Google (Page Speed) and Yahoo! (YSlow) shepherding similar projects, without trying to combine them.

10+ Deploys Per Day: Dev and Ops Cooperation at Flickr

  • Websites pretty much always ship trunk. Having versions and point releases are vestigial remnants from old shrink-wrapped product lifecycles.
  • “Dark launches”, where you use the on/off/variable conditionals to exercise the new backend before it becomes mission/feature-critical.
  • Have all deployments notify IRC/IM/Twitter (to internal teams only) so EVERYONE knows what’s going on. Also, keep it around w/timestamps, and make it searchable
  • Give ALL developers (at least read-only) access to the prod machines. It helps them help you (Ops) better.
  • If there is an outage, EVERYONE stops working on new work. Even they aren’t directly responsible, JR engineers should be working to understand why something is broken. This is a good time for them to learn these diagnostic skills.
  • AUTOMATE your INFRASTRUCTURE!!

Scaling for the Expected and Unexpected

  • ‘Planned Degradation’ – switch off functionality, this can lighten the load on the back end
  • If you hit high (un)expected load it is usually on a single/few page(s), route to a static copy of that page, regenerate every X minutes.
  • The simple act of using a proxy server between your appServer and the outside world, even if it is not caching (like Squid/Varnish), is that the appServer is just delivering to a network neighbor, reducing its thread pool contention. This simple fact can have a great positive effect on your server performance.
  • Watch out for cache stampedes.
  • 3rd Party Resources – Load last, place at bottom of page, in an iframe. If sales doesn’t like it, tell them to go to hell. (Me: whoa.)

Infrastructure in the Cloud Era

  • (Me: There were some great slides here, I hope they post them publicly.)
  • With provisioning becoming so quick (minutes), we need a quicker way to get these provisioned machines up and running quickly to realize those benefits.
  • The real benefit of the cloud is not $$, it is TIME (which you can turn into $$).
  • Definition – meatcloud: the humans that run your cloud presence. Noticeably difficult and slow to provision a new resource in your meatcloud.
  • A bit of operational philosophy – once you get your provisioning/setup all automated and quick, if a service is misbehaving have a bias towards killing it and recreating an instance, rather than trying to ‘recover’ the problem box.
  • When you’ve got Command & Control systems in place, they also need an on/off switch, because sometimes you *do* need to do some manual stuff.

Ajax Performance

  • Modify your nodes before you attach them to the DOM. Modifying them after can trigger cascading re-parsing by the browser.
  • While most languages have Optimizers, JavaScript doesn’t. You should remove your own common subexpressions / loop invariants / etc.
  • Prefer “[array, of, strings].join()” over “array + of + strings” because the “+” operator builds lots of spurious interstitial objects

Building OpenDNS Stats

  • This talk was about a High-Write environment, which isn’t as applicable to Gallery, but is applicable to our Metrics app
  • Don’t use auto-increment in a high-write environment, as it does a table_lock

Load Balancing Roundup

  • This presenter is a committer for Perlbal and was very up-front that this talk would be heavy on the praise for it.
  • Graphs that look at load every 30 seconds or more DON’T give you enough info about load on your server. Presenter suggests you watch “top -d 0.5″ for a while to get an idea of your server’s load.
  • Presenter and audience agreed that HAProxy doesn’t work with “keep-alive”

24 June 2009

Ignite Velocity 2009

Filed under: General — nelz9999 @ 22:59

My good friend Jesse asked me to consider doing an Ignite talk at the Velocity conference. I hemmed and hawed for a while, but after being assured that I could do a talk on a non-technical subject, I agreed.

I submitted the talk "Adopting SF Prankster Culture – One geek’s 10-year journey to find an outlet for his social creativity." I have posted the slides, but unfortunately those slides don’t convey a lot of information without my running commentary. I would have posted a video, but there was some problem with the video recording at the event, so I don’t think I’ll have access .

It was a really fun time. I did get a bit nervous ahead of time, but I just had to remind myself that I had just jumped out of a plane two days earlier. With that perspective, I was able to take the stage pretty confidently.

I did have a bit of a false start though, because the slides that were on the monitors right when I started were for another presenter. I did my best to bullshit my way through a slide or two until the organizers figured out the glitch. I think this actually softened up the audience with a bit of humor, which got them ready for my talk which I gave one deck later.

Doing the talk had some unexpected benefits too… For the whole next day that I was at the Velocity conference sessions, people would come up to me in the hallways and congratulate me for my presentation. I felt kinda like a geek rock star!

So if you have a chance, I would totally recommend doing an Ignite talk. I’m glad I got to ‘cut my teeth’ doing a talk on a social concept as practice in case I end up making a presentation on any of my other more technical projects.

28 May 2009

The Life of a boolean

Filed under: Java — nelz9999 @ 23:59

Java booleans came up in conversation today, and I wanted to point out a couple of things that I’ve noticed.

Firstly, when talking about (capital ‘B’) Booleans, it is possible to achieve a trinary state object: TRUE/FALSE/null. However, it is not recommended. In fact, I’d go so far as to recommend breaking the fingers of anyone who tried to perpetrate this horrible pattern in your code.

Secondly, I’d like to discuss booleans in your model objects. I agree that it frequently seems like a good idea to include one in your model object. However, I have seen so many occurrences where, over time, it becomes necessary to add a third (or fourth, or fifth) state. Even the RDBMSes are hedging their bets by storing boolean flags as TINYINTs. I would suggest that you seriously consider using an Enum to represent your two states as they exist at the beginning of their lifecycle… This way you won’t get stuck with a bunch of isXXX() accessors that all have to be refactored as soon as you add a third state.

20 May 2009

Simple-Spring-Memcached Reached RC1!!!

Filed under: Simple-Spring-Memcached — nelz9999 @ 20:28

Over the past 8 months or so, I have been working on a side project at Project Hosting on Google Code, called Simple-Spring-Memcached.

The inspiration came to me while working with memcached and the spymemcached client for Widgetbox.

I have gotten the code to the point where I feel it is good enough for prime time, so tonight I cut a 1.0.0-RC1 branch.

I’m not going to go into great detail here, as it would be a repeat of what I put up as the projects documentation. But please feel free to visit the project page and let me know what you think!

13 May 2009

JDK 1.6 on OS X

Filed under: Java — nelz9999 @ 15:32

For Widgetbox I was recently tasked with investigating a new Java memcached client called xmemcached.

Things were going smoothly (except that the xmemcached documentation is written mostly in Chinese)… But then I hit a bump in the road: the xmemcached JAR file was compiled for JDK 1.6.

Up until this point, all our code was using JDK 1.5, and we had only vague plans to eventually upgrade to JDK 1.6. Upon discussion, I’m just gonna work on the 1.6 stuff in a branch until we get the rest of the development team and operating environments up to a JDK 1.6 standard.

So, I went about upping my chosen JDK via the "Java Preferences" dialog.

Now, I saw something like this:

$ java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode)

Awesome. That’s exactly what I wanted!

But hold the phone, I was also getting this:

$ mvn -v
Maven version: 2.0.9
Java version: 1.5.0_16
OS name: "mac os x" version: "10.5.6" arch: "i386" Family: "unix"

So, I did some digging. With some hints, I found that the executable /usr/bin/mvn uses the symlink "CurrentJDK" to figure out which JDK to run, and the "Java Preferences" panel doesn’t update that when you change JDKs. (Dumb!)

So, here’s how I fixed it:

$ cd /System/Library/Frameworks/JavaVM.framework/Versions/
$ ls -la
...
lrwxr-xr-x   1 root  wheel    5 Sep 29  2008 1.5 -> 1.5.0
drwxr-xr-x   8 root  wheel  272 Feb 21  2008 1.5.0
lrwxr-xr-x   1 root  wheel    5 Sep 29  2008 1.6 -> 1.6.0
drwxr-xr-x   8 root  wheel  272 May  6  2008 1.6.0
lrwxr-xr-x   1 root  wheel    3 May 12 18:18 CurrentJDK -> 1.5
...
$ sudo rm CurrentJDK
$ sudo ln -s 1.6 CurrentJDK

Now, I am seeing the environment I want:

$ ls -la
...
lrwxr-xr-x   1 root  wheel    5 Sep 29  2008 1.5 -> 1.5.0
drwxr-xr-x   8 root  wheel  272 Feb 21  2008 1.5.0
lrwxr-xr-x   1 root  wheel    5 Sep 29  2008 1.6 -> 1.6.0
drwxr-xr-x   8 root  wheel  272 May  6  2008 1.6.0
lrwxr-xr-x   1 root  wheel    3 May 12 18:18 CurrentJDK -> 1.6
...
$ mvn -v
Maven version: 2.0.9
Java version: 1.6.0_07
OS name: "mac os x" version: "10.5.6" arch: "x86_64" Family: "mac"

25 March 2009

Java 5 Auto-Unbox Is Not NULL Safe

Filed under: Java — nelz9999 @ 16:03

Yuck!

I am kinda getting fed up with the way the language implementers of Java continually add all these conveniences, but leave them 1/2 baked.

Example:

01public class UnboxTest {
02    @Test
03    public void testUnbox() {
04        final Integer a = Integer.valueOf(10);
05        final Integer b = null;
06        unboxIt(a);
07        unboxIt(b);
08    }
09    void unboxIt(final int value) {
10        System.out.println("Value: " + value);
11    }
12}

Guess what happens when you run this code?

A big, fat NullPointerException on line 7.

Oh yeah… Autoboxing is supposed to be soo helpful, but they can’t default a frigging null to the default value of an int. (I.e. 0)

See my previous post for similar problems in the Java 5 foreach syntax.

27 January 2009

Nelz’ Micro Relief Plan

Filed under: General — nelz9999 @ 23:01

Geez, this economy is sucking! As of late, there doesn’t seem to be a day that goes by when I don’t hear of layoffs, either from mass media or from my Twitter stream.

It is in times like these when we should take time to appreciate what we have. I feel very fortunate to be gainfully and happily employed at Widgetbox. Will and Giles and our Board of Directors have done a great job of managing our funding, so much so that I know I have job for at least two more years. I daily experience a bit of cognitive dissonance when I realize that my position in a startup is more secure than many people in established companies.

I have been running around wrapped in my cozy little security blanket of a job. Sure, I’ve acknowledged that the economy is tough for a lot of people. I’ve even been trying to do my part by spending in local businesses. But the severity of the economic situation didn’t really rock me to my core until last night.

I was having a drink with a friend who does fine finish carpentry, and we started discussing how difficult things are out there. It turns out he is actively thinking about re-enlisting in the Navy after nigh 20 years away. He feels this is one of the few choices left to him to support his family. This really shook me up. Tonight, I called some of my best friends to quiz them on how they are set for maintaining their mortgage over the coming shaky financial times, because I needed to know that they are likely to be alright.

But, this is not just a time to buckle down, count my pennies, and continue living in the relative comfort that I have achieved. It is a time for action.


"No man is an island,
Entire of itself.
Each is a piece of the continent,
A part of the main.
If a clod be washed away by the sea,
Europe is the less.
As well as if a promontory were.
As well as if a manner of thine own
Or of thine friend’s were.
Each man’s death diminishes me,
For I am involved in mankind.
Therefore, send not to know
For whom the bell tolls,
It tolls for thee."
- John Donne


I feel a need to bring my blessings to bear on this economic crisis. I look about me to take stock of what I have. Whereas I am financially stable, I don’t have the financial wherewithal to employ anyone else, nor to pay for their housing. But, I do have quite a bit of space in this great apartment of mine, and I know that my privacy needs are flexible enough to deal with a shared-living-space arrangement…

Here is my proposal: If you are in my extended circle of community (Burners, techies, Twitterati, etc.) and you have suffered a financial setback (such as a layoff) and you could use some rent-relief to get back on your feet, you should get in touch with me. I am open to the opportunity of sharing my space with a fellow community member for low (or maybe even no) rent.

I don’t know what’s going to happen from this. Maybe no one wants to share a space with me? Maybe the economy makes a sharp upswing? Maybe, maybe, maybe… This is what I have to offer, and I’ll be glad if I can help someone out.

PS. I gotta give a shout-out to Toyota in this economic climate. If I were buying a vehicle, I’d prefer to support a company that operates in accordance with the very American ideals of education and recognition of service, rather than American-based companies that wallow in mismanagement and short-sightedness.

9 January 2009

SeleniumRC and FireFox3

Filed under: Java — nelz9999 @ 14:21

We have started playing with Selenium for some automated testing at my day job. (I’ve been a proponent of Selenium, but I haven’t played with it directly for a bit.)

I ran into a problem, as described by the Space Vatican. Luckily, he also had the solution to the problem.

I took his command-line instructions and created two scripts to run those command on a given file (’cuz my file was named differently than the one in his script). Here are the contents of the script:

jar xf $1 customProfileDirCUSTFFCHROME/extensions/readystate@openqa.org/install.rdf
jar xf $1 customProfileDirCUSTFFCHROME/extensions/{538F0036-F358-4f84-A764-89FB437166B4}/install.rdf
jar xf $1 customProfileDirCUSTFFCHROME/extensions/\{503A0CD4-EDC8-489b-853B-19E0BAA8F0A4\}/install.rdf
jar xf $1 customProfileDirCUSTFF/extensions/readystate\@openqa.org/install.rdf
jar xf $1 customProfileDirCUSTFF/extensions/\{538F0036-F358-4f84-A764-89FB437166B4\}/install.rdf
jar uf $1 customProfileDirCUSTFFCHROME/extensions/readystate@openqa.org/install.rdf
jar uf $1 customProfileDirCUSTFFCHROME/extensions/{538F0036-F358-4f84-A764-89FB437166B4}/install.rdf
jar uf $1 customProfileDirCUSTFFCHROME/extensions/\{503A0CD4-EDC8-489b-853B-19E0BAA8F0A4\}/install.rdf
jar uf $1 customProfileDirCUSTFF/extensions/readystate\@openqa.org/install.rdf
jar uf $1 customProfileDirCUSTFF/extensions/\{538F0036-F358-4f84-A764-89FB437166B4\}/install.rdf

And if you’d like, and feel like trusting me, here is the resultant, FF3-friendly, jar file : selenium-server-1.0-beta-1.jar

18 October 2008

Compile-Time Dependencies

Filed under: Java — nelz9999 @ 11:57

When building out your architecture, I would encourage you to break out your APIs as first-class modules. (Sorry, a ‘module’ is Maven speak for the parts of a project that create their own artifacts such as JAR or WAR files.)

For an example of a simple suggested structure, look at the following image. (Arrows denote compile-time dependencies.):

IdealModule

In some of my recent projects I received some push-back on breaking out the APIs. The concern was that breaking them out as modules would add overhead to the build process. I do understand that concern, but I think it is a minimized threat if you are using a fairly sophisticated build system.

I acquiesced at the time, and now we have a structure that looks similar to the next image. (Can you see the problem already?):PreviousModule

The black arrow indicates just one of the weaknesses of this model. Here, you can see that a UI component can (at the least offensive) access the DAO API as well as (at the most offensive) access the concrete DAO implementations.

When you have a structure like this, the question is not if, but when will one of your fellow engineers take advantage of this and circumvent the nice functional striations that you have taken so much time to isolate?

Older Posts »

Blog at WordPress.com.