Friday Fixes

April 20th, 2012 Comments off

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

This week’s challenges ran the gamut, but there’s probably not much broad interest in consolidated posting for store-level no advice chargebacks, image format and compression conversion, SQLs with decode(), 798 NACHA addenda, or many of the other crazy things that came up.  So I’ll stick to the web security vein with a CSRF detector I built.

Sea Surf

If other protections (like XSS) are in place, meaningful Cross-Site Request Forgery (CSRF) attacks are hard to pull off.  But that usually doesn’t stop the black hats from trying, or the white hats from insisting you specifically address it.

The basic approach to preventing CSRF (“sea surf”) is to insert a synchronizer token on generated pages and compare it to a session-stored value on subsequent incoming requests.  There are some pre-packaged CSRF protectors available, but many are incomplete while others are bloated or fragile.  I wanted CSRF detection that was:

  • Straightforward – Please, no convoluted frameworks nor tons of abstracted code
  • Complete – Must cover AJAX calls as well as form submits, and must vary the token by rendered page
  • Flexible – Must not assume a sequence of posts or limit the number of AJAX calls from one page
  • Unobtrusive – Must “drop in” easily without requiring @includes inside forms.

I also wanted to include double submit protection, without having to add another filter (certainly no PRG filters – POSTs must be POSTs).  Here below is the gist of it.

First, we need to insert a token.  I could leverage the fact that nearly all of our JSPs already included a common JSPF file, so I just added to that.  The @include wasn’t always inside a form so I added the hidden input field via JavaScript (setToken).  I used a bean to keep the JSPF as slim as possible.

<jsp:useBean id="tokenUtil" class="com.writestreams.TokenUtil">
	<% tokenUtil.initialize(request); %>
</jsp:useBean>
 
<script>
	var tokenName = '<c:out value="${tokenUtil.tokenName}" />';
	var tokenValue = '<c:out value="${tokenUtil.tokenValue}" />';	
 
	function setToken(form) {
		$('<input>').attr({
   			type: 'hidden',
    		id: tokenName,
    		name: tokenName,
    		value: tokenValue
		}).appendTo(form);	
	}
 
	$("body").bind("ajaxSend", function(elm, xhr, s){
		if (s.type == "POST") {
			xhr.setRequestHeader(tokenName, tokenValue);
   		}
	});	
</script>

I didn’t want to modify all those $.ajax calls to pass the token, so the ajaxSend handler does that.  The token arrives from AJAX calls in the request header, and from form submits as a request value (from the hidden input field); that gives the benefit of being able to distinquish them.  You could use a separate token for each if you’d like.

The TokenUtil bean is simple, just providing the link to the CSRFDetector.

public class TokenUtil {
	private String tokenValue = null;
	public void initialize(HttpServletRequest request) {
		this.tokenValue = CSRFDetector.createNewToken(request);
	}	
	public String getTokenValue() {
		return tokenValue;
	}
	public String getTokenName() {
		return CSRFDetector.getTokenAttribName();
	}	
}

CSRFDetector.createNewToken generates a new random token for each page render and adds it to a list stored in the session.  It does JavaScript-encoding in case there are special characters.

public static String createNewToken(HttpServletRequest request) {
	HttpSession session = request.getSession(false);		
	String token = UUID.randomUUID().toString();		
	addToken(session, token);
	return StringEscapeUtils.escapeJavaScript(token)	
}

A servlet filter (doFilter) calls CSRFDetector to validate incoming requests and return a simple error string if invalid.  You can limit this to only validating POSTs with parameters, or extend it to other requests as needed.  The validation goes like this:

public String validateRequestToken(HttpServletRequest request) {			
	HttpSession session = request.getSession(false);
	if (session == null) 
		return null;	// No session established, token not required
 
	String ajaxToken = decodeToken(request.getHeader(getTokenAttribName()));
	String formToken = decodeToken(request.getParameter(getTokenAttribName()));
	if (ajaxToken == null && formToken == null) 		
		return "Missing token";
 
	ArrayList<String> activeTokens = getActiveTokens(session);
	if (ajaxToken != null) {
		// AJAX call - require the token, but don't remove it from the list
		// (allow multiple AJAX calls from the same page with the same token).
		if (!activeTokens.contains(ajaxToken))		
			return "Invalid AJAX token";
	} else {
		// Submitted form - require the token and remove it from the list
		// to prevent any double submits (refresh browser and re-post).
		if (!activeTokens.contains(formToken)) 			
			return "Invalid form token";				
		activeTokens.remove(formToken);
		setActiveTokens(session, activeTokens);
	}
	return null;		
}

There you have it.  There are several good tools available for testing; I recommend OWASP’s CSRFTester.

Linkapalooza

Some useful / interesting links that came up this week:

  • Grep Console – Eclipse console text coloring (but no filtering)
  • Springpad – Think Evernote++
  • Pocket – New name for ReadItLater
  • RFC 2616 – The HTTP 1.1 spec at, well, HTTP
Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Infosec, Programming Tags: , , ,

Friday Fixes

April 13th, 2012 Comments off

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

You know the old saying, “build a man a fire and he’s warm for a day; set a man on fire, and he’s warm for the rest of his life.”  Or something like that.  I’ve been asked about tool preferences and development approaches lately, so this week’s post focuses on tools and strategies.

JRebel

If you’re sick of JVM hot-swap error messages and having to redeploy for nearly every change (who isn’t?), run, do not walk, to ZeroTurnaround‘s site and get JRebel.  I gave up on an early trial last year, but picked it up again with the latest version a few weeks ago.  This thing is so essential, it should be part of the Eclipse base.

And while you’re in there, check out their Java EE Productivity Report.  Interesting.

Data Studio

My DB2 tool of choice depends on what I’m doing: designing, programming, tuning, administering, or monitoring.  There is no “one tool that rules them all,” but my favorites have included TOAD, Eclipse DTP, MyEclipse Database Tools, Spotlight, db2top, db2mon, some custom tools I wrote, and the plain old command line.

I never liked IBM’s standard GUI tools like Control Center and Command Editor; they’re just too slow and awkward.  With the advent of DB2 10, IBM is finally discontinuing Control Center, replacing it with Data Studio 3.1, the grown-up version of the Optim tools and old Eclipse plugins.

I recently switched from a combination of tools to primarily using Data Studio.  Having yet another Eclipse workspace open does tax memory a bit, but it’s worth it to get Data Studio’s feature richness.  Not only do I get the basics of navigation, SQL editors, table browsing and editing, I can do explains, tuning, and administration tasks quickly from the same tool.  Capability wise, it’s like “TOAD meets DTP,”  and it’s the closest thing yet to that “one DB2 tool.”  I definitely recommend it.

Standardized Configuration

For team development, I’m a fan of preloaded images and workspaces.  That is, create a standard workspace that other developers can just pick up, update from the VCS, and start developing.  It spares everyone from having to repeat setup steps, or debug configuration issues due to a missed setting somewhere.  Alongside this, everybody uses the same directory structures and naming conventions.  Yes, “convention over configuration.”

But with the flexibility of today’s IDEs, this has become a lost art in many shops.  Developers give in to the lure of customization and go their own ways.  But is that worth the resulting lost time and fat manual “setup documents?”

Cloud-based IDEs promise quick start-up and common workspaces, but you don’t have to move development environments to the cloud to get that.  Simply follow a common directory structure and build a ready-to-use Eclipse workspace for all team members to grab and go.

Programmer Lifestyle

I’ve been following Josh Primero’s blog as he challenges the typical programmer lifestyle.

Josh is taking it to extremes, but he does have a point: developers’ lives are often too hectic and too distracted.  This “do more with less” economy means multiple projects and responsibilities and the unending tyranny of the urgent.  Yet we need blocks of focused time to be productive, separated by meaningful breaks for recovery, reflection, and “strategerizing.”  It’s like fartlek training: those speed sprints are counterproductive without recovery paces in between.  Prior generations of programmers had “smoke breaks;” we need equivalent times away from the desk to walk away and reflect, and then come back with new ideas and approaches.

I’ll be following to see if these experiments yield working solutions, and if Josh can stay employed.  You may want to follow him as well.

Be > XSS

As far as I know, there’s no-one whose middle name is <script>transferFunds()</script>.  But does your web site know that?

It’s surprising how prevalent cross-site scripting (XSS) attacks are, even after a long history and established preventions.  Even large sites like Facebook and Twitter have been victimized, embarrassing them and their users.  The general solution approach is simple: validate your inputs and escape your outputs.  And open source libraries like ESAPI, StringEscapeUtils, and AntiSamy provide ready assistance.

But misses often aren’t due to systematic neglect, rather they’re caused by small defects and oversights.  All it takes is one missed input validation or one missed output-encode to create a hole.  99% secure isn’t good enough.

With that in mind, I coded a servlet filter to reject post parameters with certain “blacklist” characters like < and >.  “White list” input validation is better than a blacklist, but a filter is a last line of defense against places where server-side input validation may have been missed.  It’s a quick and simple solution if your site doesn’t have to accept these symbols.

I’m hopeful that one day we’ll have a comprehensive open source framework that we can simply drop in to protect against most web site vulnerabilities without all the custom coding and configuration that existing frameworks require.  In the mean time, just say no to special characters you don’t really need.

Comments Off

On that note, I’ve turned off comments for this blog.  Nearly all real feedback comes via emails anyway, and I’m tired of the flood of spam comments that come during “comments open” intervals.  Most spam comments are just cross-links to boost page rank, but I also get some desperate hack attempts.  Either way, it’s time-consuming to reject them all, so I’m turning comments off completely.  To send feedback, please email me.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Friday Fixes

March 23rd, 2012 Comments off

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

This week’s challenges were all over the place, but I’ll focus in on just a couple of fixes in one popular category: Spring Security.

Filters : MVC :: Oil : Water

The web app I’m currently working on has some unique functions that occur at login.  Sure, it all starts with a login form, but it goes far beyond the simplified functions of standard Java EE form authentication.  Good news is, Spring MVC makes implementing these login functions nice, while Spring Security provides many of the protections we need. Bad news is, Spring Security and Spring MVC don’t play together at all.

A key reason is that Spring Security’s access control and authentication mechanisms are called upstream in the filter chain (before the controllers) and can’t access the controller’s state, session, and request.  With forms authentication (LoginUrlAuthenticationEntryPoint, UsernamePasswordAuthenticationFilter, and the like), you get one monitored post URL for authentication (by default,  j_spring_security_check) with no means for the controller to do sophisticated validation or page flow.

If I could lock myself into the strict confines of form authentication, then Spring Security’s implementation would be helpful: outside a bit of XML namespace configuration, all I’d need is a simple UserDetailsService DAO.  But I couldn’t, and trying to force it just convinced me that I really didn’t want Spring Security’s forms authentication after all.  What I really wanted was a Spring MVC login process which passed authentication details to Spring Security when done.

That part was very easy.  I just wrote a small utility class which, after it authenticated the user and retrieved his authorities, simply set them in Spring Security’s context.  Like so:

/**
 * Notify Spring Security that we've logged in and initialize
 * authorities for downstream filtering.
 */
public void login(MyUser myUser, HttpSession session) {
	List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();	
	for (String str : myUser.getAuthorities()) {
		authorities.add(new SimpleGrantedAuthority(str));
	}
	UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
				myUser.getUserId(), myUser.getPassword(), authorities);	   
	SecurityContext securityContext = SecurityContextHolder.getContext();
	securityContext.setAuthentication(auth);
	session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);		
}

To update Spring Security at logoff, I just did this:

SecurityContextHolder.getContext().setAuthentication(null);

This made Spring Security and me both happy, with no need to mix the oil of Spring MVC controller flow with the water of Spring Security authentication filters.

Casting Custom SPeLs

Among its many uses, the Spring Expression Language (SpEL) allows for flexible URL filter (intercept-url) expressions.  And custom expressions can be used to support unique access control requirements through simple configuration.

The T(my.package.Class).myMethod(whatever) syntax was one option, but that’s ugly, limited, and prone to error.  Further, by stepping through the code, I learned that the expression handlers called in Spring Security have access to all sorts of useful information to make authorization decisions.  So building my own custom expression evaluator was just the ticket.

But plugging in a custom expression handler took some maneuvering.  Turns out, you can’t just add a new SecurityExpressionRoot directly in the security configuration; you have to swap in a custom SecurityExpressionHandler and have it instantiate the evaluator, like so:

public class MySecurityExpressionHandler extends DefaultWebSecurityExpressionHandler {
	@Override
	protected SecurityExpressionRoot createSecurityExpressionRoot(
				Authentication authentication, FilterInvocation fi) {
		WebSecurityExpressionRoot root = 
				new MySecurityExpressionRoot(authentication, fi);
		root.setPermissionEvaluator(getPermissionEvaluator());
		return root;
	}
}

To round out the example, here’s a template for the custom evaluator and security context configuration.

public class MySecurityExpressionRoot extends WebSecurityExpressionRoot {
	public MySecurityExpressionRoot(Authentication a, FilterInvocation fi) {
		super(a, fi);
	}	
	public boolean canIDoThis() {
		// Your clever authentication here.
		// 'this' has access to the authentication token, request, and other goodies.
		// If conditions are satisfied, return true; otherwise...
		return false;
	}
}
<http use-expressions="true" ... >   	
	<intercept-url pattern="/public/stuff/**" access="permitAll"/>  
	<intercept-url pattern="/private/stuff/**" access="denyAll"/>  
	<intercept-url pattern="/members/only/stuff/**" access="isAuthenticated()"/>  
	<intercept-url pattern="/conditional/stuff/**" access="canIDoThis()"/>        
	<expression-handler ref="mySecurityExpressionHandler" />
 
	... other configuration ...
</http>	
<beans:bean id="mySecurityExpressionHandler"
         class="com.writestreams.security.MySecurityExpressionHandler"/>

Note that using expression-handler under http requires Spring Security 3.1 or higher, or at least an XSD patch.

Linkapalooza

Some useful / interesting links that came up this week:

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Friday Fixes

March 16th, 2012 Comments off

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

Hashes Make for Poor Traces

SQL and parameter tracing  is covered well by most ORMs like Hibernate, but you’re on your own when using JDBC directly.  It’s helpful to funnel JDBC access through one place with a common wrapper or utility class, but if all you get is the PreparedStatement, there are no public methods to get the SQL text and parameter array from it for tracing.  Unbewiebable.  PreparedStatement.toString sometimes includes useful information, but that depends entirely on the JDBC driver.  In my case, all I got was the class name and hash.  So I just went upstream a bit with my calls and tracing hooks so I could pass in the original SQL text and parameter array.

Samy Isn’t My Hero

You’d think URL rewriting went out with the Backstreet Boys, but unfortunately, JSESSIONID is alive and well, and frequenting many address bars.  This week, I’ve been focused on hack-proofing (counting down the OWASP Top Ten) so I should be a bit more sensitive to these things.  Yet I inadvertently gave away my session when emailing a link within the team management system I use (does it count as a stolen session if you give it away?)  Not only does this system include the direct sessionguid in the URL, it also doesn’t validate session references (like by IP address) and it uses long expirations.

At least this system invalidates the session on logout, so I’ve resumed my habit of manually logging out when done.  That, and attention to URL parameters is a burden we must all carry in this insecure web world.  Site owners, update your sites.  Until then, let’s be careful out there.

Virtual Time Zone

While directing offshore developers last year, thinking 9 1/2 or 10 1/2 hours ahead finally became natural.  Having an Additional Clock set in Windows 7 provided a quick backup.  Amazingly, some software still isn’t timezone-aware, causing problems such as missed updates.  I won’t name names or share details, but I opted for a simple solution: keep a VM set in IST and use it for this purpose.  Virtual servers are cheap these days, and it’s easy enough to keep one in the cloud, hovering over the timezone of choice.

SQL1092 Redux

Yes, bugs know no geographical boundaries.  A blog reader from Zoetermeer in the Netherlands dropped me another note this week, this time about some SQL1092 issues he encountered.  Full details are here; the quick fix was the DB2_GRP_LOOKUP change.

This DB2 issue comes up frequently enough that DB2 should either change the default setting or also adopt WebSphere MQ’s strategy of using a separate limited domain ID just for group enumeration.  Those IBM’ers should talk.

Those Mainframe Hippies

I traditionally think of mainframe DB2′ers as belt-and-suspenders codgers who check your grammar and grade your penmanship, while viewing DB2 LUW users as the freewheeling kids who sometimes don’t know better.  That changes some with each new version, as the two platforms become more cross-compatible.

So I was surprised this week to find that DB2 for z/OS was more flexible than DB2 LUW on timestamp formats.  Mainframe DB2 has long accepted spaces and colons as separators, but unlike DB2 LUW, you can mix and match ‘em.  For example, DB2 z/OS 9 and higher will take any of the following:

’2012-03-16 19:20:00′

’2012-03-16-19.20.00′

’2012-03-16-19:20:00′

’2012-03-16 19.20.00′

DB2 LUW (9.7) will reject the last two with SQL0180 errors.

Knowing the limits is important when writing code and scripts that work across multiple DB2 platforms and versions.  The problem could get worse as DB2 LUW adds more Oracle compatibility, but as long as the DB2 kids and codgers stay in sync, we can enjoy some format flexibility there.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Friday Fixes

March 9th, 2012 2 comments

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

It’s a Big World After All

I got the complaint again this week: “DB2 is so stupid; why does it sometimes take two bytes for a character?”  I’ve answered that before, and the best solution is: if you’re storing truly binary data, use a binary type (like for bit data).  But if it really is text, I usually just send a link to Joel Spolsky’s classic article on character encodings.  And here’s a quiz – let me know what the following says:

אם אתה יכול לקרוא את זה, אתה תגרוק קידודים

The counterpoint to Joel’s article, or at least to blindly applying Postel’s Law to web apps, is that it can open the door to all kinds of security vulnerabilities: SQL injection, cross-site scripting, CSRF, etc.  So it’s common to have a blacklist of disallowed characters or a white list specifying the allowed character set.  The point is to be deliberate and think about what should be allowed: both the extent and limits.  Don’t treat binary data as text and don’t pretend there’s only one character encoding in the world.

Different, Not Better

Having endured VMWare’s product gyrations through the years, I’ve learned that upgrading it isn’t always best: sometimes I just get different, not better.  I feel the same way about Windows 8.

In this latest case, I found my beloved but now-obsolete VMWare Server can’t host the new Windows 8 CP edition, so I considered switching to VMWare Workstation 8.  But the latest VirtualBox (4.1.8) works, so I downloaded that, installed Windows 8 from ISO, and quickly had it running in a VM.  Glad I didn’t have to play a pair of 8s.

I suppose that’s a side benefit when leading players like VMWare and Microsoft make revolutionary changes to their incumbent products.  Major (often costly) upgrades create good opportunities to try out competing alternatives.

That Other Browser

I’ll always need the latest Windows and Internet Explorer (IE) versions running in some mode (VM or otherwise) just to test and fix IE browser compatibility issues.  This week, I ran into an “Access denied” JavaScript error in IE 8 – Intranet zone, Protected Mode.  As is often the case, my code worked fine in Firefox, Chrome, and other browsers.

I wanted to pin down exactly which IE setting was causing the problem, so I tweaked some likely suspects in custom Security Settings but could never nail it down to just one.  There was nothing in the Event Log to really help, just red herrings.  And apparently neither Protected Mode nor IE ESC was the root cause.  Switching zones (such as adding to trusted sites) didn’t work either, and extreme measures only made things worse.  Ultimately, doing a Reset all zones to the default level resolved the issue.

IE has far too many obscure and non-standard security settings that don’t work as expected.  And there’s no direct way to get a consolidated dump of all current settings.  Microsoft continues to work on fixing this, so I’m hopeful things will improve; they really can’t get worse.  Until then, the solution may continue to be “switch browsers” or “take one reset and call me in the morning.”

Jasper Variability

Jasper Reports (iReport) variables and groups are useful features.  But they can be frustrating at times because of documentation limits (yes, even with The Ultimate Guide) and differences between versions and languages (Groovy v. Java).  Sometimes the answer must be found by stepping through the code to determine what it wants.  That was necessary for me to get my group totals working.

For example, imagine a sales report grouped by region where you want group footers totaling the number of Sprockets sold for each region.  Standard variable calculations won’t work, and the Variable Expression must handle anything that comes its way, including null values from multi-line entries.  So, rather than using a built-in Counter variable with an Increment Type, I had to use a counter-intuitive variable, like so:

Property Value
Variable Class java.lang.Integer
Calculation Nothing
Reset type Group
Reset group regiongroup
Increment type None
Variable Expression ($F{TYPE} != null && $F{TYPE}.equals(“Sprocket”)) ? new java.lang.Integer($V{sprtotal}+1) : $V{sprtotal}
Initial Value Expression new java.lang.Integer(0)

In JRXML, that comes to:

	<variable name="sprtotal" class="java.lang.Integer" resetType="Group" resetGroup="regiongroup">
		<variableExpression><![CDATA[($F{TYPE} != null && $F{TYPE}.equals("Sprocket))?new java.lang.Integer($V{sprtotal}+1):$V{sprtotal}]]></variableExpression>
		<initialValueExpression><![CDATA[new java.lang.Integer(0)]]></initialValueExpression>
	</variable>

Linkapalooza

Some useful / interesting links that came up this week:

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Friday Fixes

March 2nd, 2012 Comments off

It’s Friday, and time again for some Friday Fixes: selected problems I encountered during the week and their solutions.

CSS – Space Matters

Guess you could say I was “lost in [a] space” wondering why my browser didn’t pick up my div’s CSS class.  Turns out, I wrote the selector as #myid .myclass (descendent selector) but really meant #myid.myclass (combined selector). Thank you, 2.5x reading glasses and Chris Coyier, for the quick save.

Point of No Return

JavaScript and jQuery iterator functions are awfully convenient, but it’s easy to overlook scope.  While refactoring some code today, I wrapped a function around some iterator code for reuse and broke it. Here’s a simplified example to demonstrate the problem:

     function myFunction() {
        $.each(['a', 'b', 'c'], function(idx, ea) {
           if (ea === 'b') {
              return ea;
           }
        });
     }

At a glance, you’d think myFunction returns b, but since the inner function’s result is never passed out, it returns undefined.  And jQuery’s each method just returns the collection, so adding a return in front doesn’t help.  jQuery does have some alternatives (like filter) that can help, but those aren’t as flexible as each.

The simple solution is to just carry the value to the outer scope, like so:

     function myFunction() {
        var result;
        $.each(['a', 'b', 'c'], function(idx, ea) {
           if (ea === 'b') {
              result = ea;
              return false;
           }
        });
        return result;
     }

Adding the “return false” stops the iteration at the first match.

Is this Thing Used?

My current project has this DB2 LUW fan coding against a DB2 for z/OS database.  While I give up a some things, I also gain a lot.  For example, while working on a DAO, I had questions about a particular table’s indexes.  Fortunately, DB2 for z/OS has SYSINDEXPLANSTATS which, among other things, keeps track of the last time an index was used (even for dynamic SQL) to help determine its merits.  So I first checked to see if this was at least version 9:

select getvariable('SYSIBM.VERSION') from sysibm.sysdummy1;

… and then answered my questions with a simple query like the following:

select i.name, i.tbname, i.creator, i.uniquerule, i.colcount, i.clustering, s.lastused
from sysibm.sysindexes i, sysibm.sysindexspacestats s
where i.name = s.name
and i.creator = s.creator
and i.dbname = 'MYDB'
and i.tbname like 'MYPREF%'
order by s.lastused

Can’t wait for this to make its way to DB2 LUW.

VSSibility

Yes, I presently have to use Microsoft Visual SourceSafe (VSS).  I’m over it now.  When using this “lock first” VCS against a deep project hierarchy, I often need to see a quick list of my check-outs.  I can use View->Search->Status Search (with subprojects selected) from the VSS GUI, but that’s often too slow over a remote VPN connection.  So I cooked up a quick script to run over an ssh command line from a server that is “local” to the repository:

cd /d "C:\Program Files\Microsoft Visual SourceSafe"
set SSDIR=\\myserver\VSS\myvssshare
ss STATUS $/MyProject -R -Umyusername

Flexigrid Echo

Imitation isn’t always flattering; it’s often annoying.  Having two Flexigrids on one page, both with pagers enabled (usepager: true) yielded some weird mocking behavior.  For example, paging forward on one grid caused both grids to show the same “Page X of Y” message.  After debugging, I found that similar bugs had been reported and fixed in the latest release.  Upgrading Flexigrid resolved that one.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Friday Fixes

February 24th, 2012 Comments off

Friday Fragments served a useful purpose, one of which was regularity: funny how Fridays kept coming around.  While I haven’t been in pedagogical fragment mode for awhile, I encounter real life puzzles every day.  Sharing these often helps others who encounter the same problems, or even myself when I need a quick reference down the road.  I just need a reminder and motivator to stop and record these.  I suppose Friday is as good as any.

So here goes the first installment of Friday Fixes: selected problems I encountered during the week and their solutions, along with other sundries.

Spring Loading

Like most form tags, binding a multi-select list in Spring MVC is easy: deceptively so.  All you need is this, right?

<form:select path="myFavorites" id="myFavorites" size="3" multiple="true" class="myList">
	<form:options items="${allChoices}" />
</form:select>

And, of course, the model attribute and/or bean methods to return the allChoices collection and get/set myFavorites.  Well, not so fast.  Turns out, multi-select lists in Spring MVC have always been a bit of a pain, particularly when it comes to making the initial selections (convincing Spring to add the selected attributes) on initial page load.  One pre-selection is fine, but with multiples, the comma-separated list pushed back into the model’s setter is a one-way trip.

Solving this in prior versions of Spring required using an InitBinder whether you otherwise needed one or not.  But for Spring MVC 3, the fix is to just map to collection getter/setters, even if your model wants to use the comma separated list.  For example, use the following getter and change the form:select path to use it: path=”myFavoritesList.

	public List getMyFavoritesList() {
		List list = new ArrayList();
		for (String fav : getMyFavorites().split(",")) {
			list.add(fav);
		}
		return list;
	}

Time(outs) May Change Me…

Between the deadlock event monitor, db2pd, and snapshots, DB2 has long provided good tools for tracking down deadlock culprits.  But for lock timeouts, not so much.  The DB2 folks have tried to improve things lately, but they’ve changed their minds a lot, often adding new tools and then quickly taking them away.

Now that lock timeout event monitors are finally here, many of the other new approaches like db2_capture_locktimeout and db2pdcfg -catch (with db2cos call-out scripts) have been deprecated.  A coworker was concerned about the passing of db2_capture_locktimeout, but it appears it’ll be around a little longer.  For example, the following still works in even the latest 9.7 fixpacks.

db2set db2_capture_locktimeout=on
db2stop & db2start
db2 get db cfg for sample show detail | find /i "timeout"
db2 update db cfg for sample using locktimeout 30
db2 connect to sample
db2 -c- update org set deptname=deptname

Repeat the last two commands in another DB2 Window and then wait for the timeout.  Look for the report under your DIAGPATH, SQLLIB, or Application Data folder; for example: dir db2locktimeout*.* /s.  Even with the latest 9.7 fixpacks, the timeout report can occasionally have some holes in it (like missing SQLs), but it’s still quite useful.

Flexigrid Incantation

Got a Flexigrid with a radio button?  Want to fetch the value of a column on the radio-selected row?  Well, when Flexigrid generates the tds and divs from your colModel, it provides abbr attributes, not ids.  So the usual jQuery shorthands to find by ID don’t apply, and you’re off chasing the more obscure abbr.  For example:

$('.mytable').find('tr').each(function (index, tr) {
	if($(tr).find('input#sequence').attr('checked')) {
		myvalue = $(tr).find('div#myname').val();          // Nope, doesn't work
		myvalue = $('td[abbr="myname"] >div', tr).html();  // Gotta use this
	}
});

New Toys

My own little Linkapalooza of online tools I found this week and actually used:

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Keeping Baby and Bathwater

February 17th, 2012 Comments off

After untangling some weirdness this afternoon, I feel like joining the masses storming the JavaScript Bastille.  But it’s too late for that with this “can’t live with it, can’t live without it” language.

A Big Baby

JavaScript is unmatched for its immaturity and ubiquity.  Both, of course, are intertwined.  With an installed base of a few billion JavaScript-enabled browsers out there, it’s virtually impossible to break compatibility and significantly fix this underdeveloped language.  The slow progress of the ECMAScript committee doesn’t help matters.  Hence so many “compile to JavaScript” tools and languages: GWT, CoffeeScript, Dart, etc.  But if going non-native were truly a good idea, we’d all be debugging bytecode.

As the size of our JavaScript code bases continues to explode (propagated by richer clients and SSJS), maybe we finally accept that the raw, unevolved language is here to stay and, since we can’t fix it, do a better job of propping it up.  Since many (perhaps most) JavaScript developers don’t naturally write clean code nor stick to The Good Parts on their own, we need code checkers.  Yes, I mean lint, but one that folks will actually use.

JSLint – A Good Start

If a proliferation of cross-compilers condemns a language, the proliferation of lint tools condemns its compilers, editors, and IDEs.  Lint tools typically fill the gap where a language lacks or the tools haven’t caught up or caught on.  Few people still use a separate C lint because most compilers and IDEs have integrated their most important checks.  And PMD became less important to me as I started tweaking Eclipse’s Java compiler warnings (although it still needs better file and package filtering).

There are a few JavaScript lint options; I prefer Douglas Crawford’s own JSLint and its recent JSHint fork.  It can be a bit pedantic, overemphasizing style.  Some of the trivial style checks can be disabled (for example, white: true and vars: true), while others can’t (“Mixed spaces and tabs”, really??).  But it’s helpful enough at catching things to be worth using in spite of its false alarms and awkwardness.

But what JSLint lacks most is integration: both with embedded source and standard tools.  That is, JavaScript source is often in server-side pages like JSPs, intermixed with form tags, embedded foreign language, and other noise that JSLint can’t handle.  The work-around is to let the server render it and then paste it into JSLint, but couldn’t someone integrate JSP parsing smarts with JavaScript validation?  And could we focus energies on making it an extension of Eclipse’s JavaScript validation: one that’s actually useful?

Perhaps smarter code analysis in this loose language is a hard nut to crack.

The Next Level

And that certainly makes sense: static analysis of JavaScript is hard because it isn’t just a dynamic language, it’s the wild west.  Is x a variable, function, property, or value?   Is it local, global, or forgotten?  Without true scoping, access control, and other aids, context is very hard to discern.  JSLint helps by not letting you get away with ambiguity, but arbitrary belts and suspenders aren’t the best solution.  Since we humans often have to let the JavaScript page render and step through it in Firebug to see what’s really going on, can we really expect a computer to figure it out from flat source code?

I think so.  With enough (warranted) attention, JavaScript validation will improve, and we’ll even see better code assist and refactoring tools.  It may take some new ways of looking at the problem, but fortunately, there’s some promising new research happening now.

Looks like we’re stuck with this JavaScript baby and all its dirty bathwater.  But here’s hoping future tooling makes cleaning it up a lot easier.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: ,

Upgrade and/or Die

February 1st, 2012 Comments off

JDBC is one of those core, essential components where you want to see continued incremental improvement with no interface impacts: just keep dropping in the latest versions and expect it to work.  Yay, back compatibility!

JDBC 4.0 is relatively new to DB2 LUW (first available in version 9.5), but it and prerequisite Java 6 have certainly been around long enough for folks to start switching over to it.  Just don’t assume that everything in a deep open source stack will work with it.

In yesterday’s action, perfectly-good BIRT 2.5.1 reports failed (“data set column … does not exist” exception) in an environment with DB2′s JDBC 4.x drivers.  At first, I suspected the particular db2jcc4.jar level, since it was taken from DB2 9.7 Fixpack 3: that now-deprecated fixpack that does everything evil except steal your kidneys.  But since new versions of BIRT (like the 3.7.1 version I use) worked fine with that version of Ernie (ahem, JDBC 4.0) and old versions of BIRT worked fine with JDBC 3.0 (db2jcc.jar), that flagged the culprit.  Turns out, the report SQLs use column aliases (who doesn’t?) and apparently JDBC 4.0′s getColumnName “fixes” broke these.  Upgrading BIRT brought harmony back to the universe.

With “broken compatibility” issues like this, it’s tempting to procrastinate on open source upgrades.  That’s why Maven POMs quickly develop inertia: once you get it all working together, who has time to test new dependency version permutations?  Fortunately, the Eclipse project and others do a good job of bundling compatible toolsets for download.  That way, if something “doesn’t work on my machine”, it’s quick work to see how it plays with the latest and greatest stack.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2, Programming Tags: , , ,

Measuring Wins

January 10th, 2012 Comments off

As a follow-up to Saturday’s post and last night’s BCS title game, I was asked about RPI rankings for this year.  Strength of schedule and RPI are particularly important for NCAA football where, in this era of “buy games” and weak conferences, win-loss records must be taken with a grain of salt.  It’s not just about how you play, but also who you play.

So I gathered 2011 NCAA data and ran it though the RPI programs we coded as Friday Fragments this time last year; see: http://derekwilliams.us/fragments/rpi.html.  The top 10 teams by RPI are:

Rank Name Record Win % RPI
1 LSU 13-1-0 0.929 0.701
2 Alabama 12-1-0 0.923 0.676
3 Oklahoma St. 12-1-0 0.923 0.670
4 South Carolina 11-2-0 0.846 0.643
5 Arkansas 11-2-0 0.846 0.638
6 Kansas St. 10-3-0 0.769 0.634
7 Baylor 10-3-0 0.769 0.633
8 Oklahoma 10-3-0 0.769 0.631
9 Michigan 11-2-0 0.846 0.630
10 Oregon 12-2-0 0.857 0.626

Teams like Stanford, Boise State, and Wisconsin aren’t in this top ten.  That’s because, with their low strength of schedule ratings, the computer just doesn’t like them.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: ,

Playoff Prognostication

January 7th, 2012 Comments off

“Prediction is very difficult, especially about the future.”

Niels Bohr

It’s NFL playoff time again, and seemingly everyone’s prognosticating.  Last year’s late rise of the Packers (6th seed who won it all) proved again that “past performance does not guarantee future results.”  But since a calculated guess is better than a wild one, I thought I’d run my own numbers using the power ranking tools we developed as Friday Fragments this time last year.

I gathered fresh data (2011 NFL regular season results) and ran it through http://derekwilliams.us/fragments/tourney.html.  Of the resulting top 12 teams (by power ranking), 11 are in the playoffs:

Rank Team Power
1 Packers 90
2 49ers 86
3 Saints 83
4 Steelers 83
5 Ravens 70
6 Bengals 68
7 Texans 67
8 Patriots 67
9 Giants 64
10 Lions 63
11 Falcons 61
12 Raiders 56

The Raiders (#12) didn’t make the playoffs; instead we have the Broncos who won the AFC West, but rank #22 (power 41).

This has the Packers winning it all again.  But with my Falcons at #11, I’m hoping for a few surprises, starting with tomorrow’s game against the Giants.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Just Concentrate

December 14th, 2011 Comments off

In most cases (at least for OLTP systems), using SQL parameter markers instead of literal values improves performance, adds consistency, reduces CPU overhead, and makes the database easier to monitor.  SQL parameters let DB2 cache the access plan so that compilation only happens once and execution counts are combined for the same statement.

A transaction system that carelessly uses literals can often be improved by converting literals to markers wherever possible.  But since this recoding takes time, it would be nice to predict the performance impacts (hopefully benefits) of such a change without having to just code it all and then measure.

Fortunately, DB2 9.7 offers the new Statement Concentrator to do just that.  Enabling it at the database level is easy:

db2 update db cfg for DATABASE using stmt_conc literals

And you can see if it’s enabled with:

db2 get db cfg for DATABASE | find /i “stmt_conc”

I suggested this new feature to a colleague today, and did some experiments myself.  It was nice to see the statements combined in the Dynamic SQL Snapshots, and also see the (zero-execution) literal versions separated out.  This means I’ll have to update my snapshot analysis tools which combine similar SQLs.

But the nagging feeling remains that this might be too broad a change.  For some SQLs, those unique (literal-driven) access plans are necessary.  But it may be possible to reach a good balance by enabling the statement concentrator at just the right level and by using optimization profiles for those exceptions to the rule.  That’s something worth concentrating on.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags:

Wait for it

November 22nd, 2011 Comments off

“If there are enterprise beans in the application, the EJB deployment process can take several minutes. Please do not abandon all hope while the process completes.”

WebSphere deployment message (paraphrased)

Of all the many ills of EJBs, slow deployments are among the most chronic.  New products like JRebel attempt to reduce this time impact, but with inconsistent results.  And hot-swapping code while debugging often fails for all but the most trivial changes.  So if each significant code change requires a long wait for redeployment, it at least better work.

That’s why today’s deployment failures were so annoying.  I could see from console logs that RMIC was running and there were no errors, but the EJB stub classes were missing from the resulting JARs.  This was a new MyEclipse workspace (Blue edition, version 9.1), but I had never had this problem before.  I re-checked my configuration and verified that I had enabled EJBDeploy for my WebSphere 6.1 target server (Properties – MyEclipse – EJB Deploy).  Yet in the process of poking around and checking things, I stumbled on the problem.  While there, I kicked off a manual run by clicking “Apply and run EJB Deploy” and finally got an error message: it could not create the files because it needed the .ejbDeploy sub-folder under my workspace path.  I manually created that folder and it worked.

I don’t know why MyEclipse or ejbdeploy couldn’t just create the folder, nor why it wouldn’t report the error to the console during normal deployments.  But since this manual work-around resolved the problem, I’ll know what to do next time it happens.

Problem solved, and back to waiting on deployments again.  Thanks… I think.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , ,

DB2 in Cygwin

September 29th, 2011 Comments off

I often use Cygwin with ssh and putty to remote into various Windows servers. It’s a lot quicker than Windows Remote Desktop and, well, I’m a command line junkie.  But since db2cmd defaults to launching a new window/session, it doesn’t play nicely with ssh.  Sure, I could remotely attach or catalog the node and database, but that defeats the purpose of being quick and simple.

To work around this, I add the following alias to my .bashrc:

alias db2=’db2cmd -i -w -c db2′

It’s imperfect (it works only for isolated commands or scripts), but it’s great for quick commands.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags: , ,

Please Design Responsibly

September 26th, 2011 Comments off

Handled correctly, loose typing can be a powerful thing , but with great power comes great responsibility.   The license to enjoy the benefits of dynamic typing comes with the responsibility to actually design with real objects.  If one just strings together collections of simple types, weaker typing can lead to some very confusing code.

I was reminded of this today in an improbable way.  I uplifted some old, unfamiliar code to a modern Java version, which included adding in generics: taking untyped collections toward strongly-typed ones.  This meant grokking and stepping through the code to infer data types where nested collections were used, and it smoked out what the design really looked like.  One commonly-used structure came to this, and there were several others like it:

 HashMap<String, HashMap<String, HashMap<String,
                           HashMap<String, HashMap<String, Vector<String[]>>>>>>

Wow.  I wish I was joking.

This just screams, “make objects!”  It reminded me of perhaps why the “everything in triplicate” crowd fears dynamic typing.  If you aren’t designing with objects, then strong typing partly saves you from yourself.  In this case, the addition of crazy nested generics actually made the subsequent code easier to understand and less error-prone.

But a much better approach, of course, is to create new classes to handle what these nested collections do, with the added benefit of factored behavior.  In this case, the real objects exist very plainly in the problem domain; just follow the nouns.  A truly object-oriented design usually doesn’t need strong typing to clarify the design.

This does require diligence and I’ve often been guilty of missing objects, too.  Yet perhaps this example reveals a new code quality metric: if you need more than two adjacent angle brackets to make the “raw type” compiler warnings go away, it’s time to step back and look for objects.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , ,

Merging Git and CVS

September 15th, 2011 Comments off

Today I found myself needing to run ahead of the current stream of development and code some things to be merged in later.  I needed the flexibility of easy branching and merging atop a code base that’s maintained in CVS.   CVS branches are overkill and Eclipse/CVS change set grouping is too limited.  What I really wanted was Git, but migrating wasn’t an option, and doing a full git cvsimport would take forever.  I just needed simple local changesets atop the shared CVS repository.

Fortunately, I stumbled across a simple workflow by Kris Johnson that met my needs perfectly.  I used it with a few minor variations, such as synching (cvs update) differently, using TortoiseCVS for a few operations, and doing the final commit via Eclipse (so that I could get one last look at the changes in the Synchronize view).  But it’s a very helpful process that I’ll hang on to.

While I’m jotting things down, here’s the .gitignore I created for the Eclipse/Java projects I’m working on.

CVS/

bin/
*.class
*.jar
*.zip

*.~
*.dat
*.cache
*.lock
*.log
*.out
*.swp
Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , ,

Tricky Wiki

September 14th, 2011 Comments off

A key agile principle is to do the simplest thing that could possibly work.  So it seems paradoxical that as Agile grows, so does the number of increasingly-complex tools to manage the process.  Yet a great way to manage Scrum artifacts (backlogs and burndowns) remains the simple wiki.  To this end, ComSwiki has worked well for me, as it is lightweight, flexible, and fast.

But new corp-rat standards require that I use SharePoint to the degree that “if it’s not in SharePoint, it doesn’t exist.”  So I had the admins create a SharePoint Wiki for my team, and started filling it up with backlogs, how-to’s, and other content.

Frustration soon followed as simple editing often requires deleting text and starting over.  The SharePoint Wiki’s WYSIWYG editor (only available in Internet Explorer) tries to be useful, but often just gets in the way.  For example, try adding a row or column to an existing table: it can’t be done.

Not to be deterred, I turned SharePoint’s limitation into a feature.  The WYSIWYG editor doesn’t work in Chrome and instead pops up a simple text box with the raw, ugly, generated HTML.  Yet I can edit this HTML to do things that the WYSIWYG editor won’t.  So, I now typically keep both Chrome and IE open on the same page and switch back and forth depending on what sort of editing I need to do.

It’s a stone-age approach, but then again, SharePoint is a stone-age tool.  Hopefully, the WYSIWYG editor will be improved and expanded in future releases, but until then, it would have been better for Microsoft to take a “simplest thing” approach.  That is, support the simple markup language of ComSwiki and other wikis rather than attempt a (mostly broken) WYSIWYG editor.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: ,

Not Listening

August 10th, 2011 Comments off

DB2 9.7 seems to have brought back an old problem: DB2 servers that are deaf to TCP/IP connections.  In today’s action, my JDBC connections on a new Windows DB2 9.7 configuration were hanging for several minutes and then eventually failing with a “connection refused” error.  Since such problems are usually due to configuring the wrong port, I verified it:

db2 get dbm cfg | find “SVC”

type %WINDIR%\system32\drivers\etc\services | find /i “db2″

I had specified the right port: the standard 50000 default for the first instance.  And all the standard DB2 tools connected to the database just fine, including CLP and CLI connections.  After checking all the wrong places, I finally looked to see if DB2 was actually listening on this port:

netstat -an | find “500″

telnet localhost 50000

It wasn’t: I got no relevant matches on the netstat and telnet gave the “connect failed” error.  I checked DB2COMM and found it didn’t include TCP/IP.  Weird.  So I quickly remedied that with:

db2set DB2COMM=tcpip & db2stop & db2start

And verified with:

db2set -all db2comm

I’m not sure why some recent new DB2 9.7 installs didn’t have TCP/IP connections enabled by default.  Usually, it’s the setup/db2setup default.  But it’s something I’ll watch for, with a quick solution next time.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags:

The Flash Cache Flush

July 30th, 2011 Comments off

We all endure software that seems to grow worse with each upgrade; for me, that includes Ubuntu, the Weather Channel App, and Flash.  I try clinging to the “oldies but goodies” for as long as I can (for example, I use my 9.10 Ubuntu VM far more than my 11.04 one), but forced upgrades are usually inevitable.  Flash is one very necessary evil that must be kept current: it’s either upgrade or stop using some sites.

After a brief period of continually-improving releases, Flash is giving me fits again, at least with the 10.3 version.  I’m again getting bizarre behavior with sites like Nike+, requiring periodic work-arounds.  One often effective fix for Flash problems is to clear its cache.  Fortunately, that’s a quick process:

  1. Open the Flash Settings Panel by hitting this URL: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html.
  2. Scroll through the Websites list to locate and select the site with “issues.”
  3. Click Delete Website.

This often clears things up.

This handy URL shows the installed flash version.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Lifehacks Tags:

Summer Running

July 26th, 2011 Comments off

“Heat, hills, and humidity.  Welcome to Atlanta.”

Run Atlanta slogan

While summer adds heat to the challenge of running, it also brings time in the schedule for racing.  My daughter Lydia and I ran several races over the past couple of months; here are a few of them.

Celebrate America 10K

For Memorial Day, we ran the Celebrate America race at Alpharetta’s Northpoint Mall.  This 16th annual event was well organized and equipped, making for a smooth race of nearly 900 runners.  The course was pleasant – a loop on tree-lined streets around the mall area, with a few rolling hills.  The 10K was a double loop, which provided an extra benefit for me: I was able to watch Lydia cross the 5K finish line as I started my second time around.  Lydia won her age group in the 5K at 25:00; my 10K time was 53:02.

There were several Memorial Day races in the area, and I’m pleased that we chose this one.  We’ll watch for it again next year.

ATC Fathers Day 4 Miler

The Atlanta Track Club (ATC) held its annual Fathers Day 4-Miler on Saturday, June 18, the day after Tina and I returned from our 25th anniversary trip.  It had the benefits of being free for ATC members and ending inside Turner Field: the Braves home plate area makes a great place for the finish line.

The course was well-planned, through the historic neighborhoods of downtown Atlanta, past Grant Park and the Atlanta Zoo.  There were some challenging uphills, but good downhills to recover.  I enjoyed running alongside Lydia the entire time and crossing the finish line together.  I was proud of her for doing well on the 4 mile distance and hilly course.  Our team finished 22nd overall at 36:47.

Peachtree Road Race

No other race matches the excitement of the world’s largest 10K.  And with 60,000 runners, the 42nd annual Peachtree Road Race was the largest yet.   On July 4, Stephen and Lydia ran the Woodstock Freedom Run, while I headed downtown for the Peachtree.  Getting there is the hardest part: waking in the darkness of 4:00 am and driving to the nearest Marta rail station before the parking lots fill up.

The new time groups make the crowds manageable: it becomes more like 22 serial races of about 3,000 runners each than a mob of 60K.   I was in corral C which, fortunately, is one of the four start waves with access to the starting line area.  This provided more space to relax and explore and enjoy the pre-race activity and wheelchair division start.

Another first this year was a flyover by three F-16s to close the national anthem – a flyover at a 10K – how cool is that?  That added to the excitement of the start, which continued throughout the race.  The entire course is lined with bands, giveaways, spectators (over 100,000), TV and radio stations, costumes, and some unique Independence Day celebrations.  As my college “stomping grounds”, the route also brought back many memories.  All this carried me along so that it felt more like a celebration than a race.  I hardly noticed the heat and “cardiac hill.”

There’s quite a bit of “sideways running” to weave around crowds and dodge fire hoses, so the Peachtree isn’t a race for PRs.  I kept an even pace and finished at 54:01, par for the Wave C course.

This race just gets better every year, and the current ATC leadership is doing a great job of implementing smart improvements.  Taking the AJC’s post-race poll revealed a lot of popular suggestions: tweak the start waves for groups, switch to a technical T-shirt, start earlier.  But, even if nothing changes, I’ll be back next year: me and 60,000 fellow runners.

Etowah River Run

The annual Etowah Swelter River Run balances the benefit of a fast course with the challenge of late July heat.  This year, like last, was certainly no exception: race time weather was at 77 degrees with 91% humidity, but that was offset by the signature opening downhill run and flat-as-a-pancake route.  This was the third year running it for Lydia and me; she finished first in her age group at 25:06, while I came in at 24:23.

The race held many familiar positives: fast course, helpful volunteers, good local turnout (about 500 runners, including a few cross country teams), nice T-shirt design (a repeat of last year’s popular art), valuable and plentiful door prices, and close proximity to home.   This year’s introduction of D-tag chip timing was a nice improvement.  I’d like to see the race start earlier to beat some of the heat, and a technical (rather than cotton) T-shirt would be nice.  As in years past, a few runners complained that the course was a little long (from 3.18 to 3.22 miles), but that narrow discrepancy is really only a concern to folks looking for new PRs.  We’ll be back again next year, pushing the pace against the heat.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Family, Running Tags: