A collection of thoughts, ideas and rants inspired by my career in the fintech and banking industry.

How to show which .hgrc Mercurial is using

Mercurial loads a bunch of different configuration files and overlays their values on top of each other. The hgrc man page shows the order in which these files are loaded.

I encountered an issue recently where I knew that hg was using an erroneous setting but I had no idea where the setting was coming from.

The magic answer is

hg --debug showconfig  

This will output all the current settings, along with the name of the file that it got each setting from. Very useful indeed.

[Read More]

How to take local in Mercurial without a merge conflict

When there’s a merge conflict in Mercurial, TortoiseHG will give you the option to ’take local’ or ’take other’ in addition to resolving the conflict.

However, sometimes you may want to ’take local’ or ’take other’ when there’s no merge conflict.

To take local:

hg merge --tool internal:local <rev>  

To take other:

hg merge --tool internal:other <rev>  

Broken Generics

Given the following code

Map<String, String> map = new HashMap<String, String>();  
map.put("123", "value");

Integer key = Integer.valueOf(123);  
String actual = map.get(key);  

What is the value of “actual”?

  1. Compilation error - key should be a String
  2. “value”
  3. null

Answer: null

This blew me away. The whole point of type-safe collections was supposed to provide compile-time checking. However, the only generics method on the Map class is put(K, V). So calling get(Object) doesn’t cause a compilation error, but merely returns null.

[Read More]
Java 

Slow Mercurial clone

I recently set up a Mercurial server (Windows, Apache, ActiveDirectory and hgweb.wsgi). However, cloning our 1Gb repository took an hour or more and often failed.

The only information in the Apache log was

mod_wsgi (pid=1234: Exception occurred processing WSGI script
'C:/hg/hgweb/hgweb.wsgi'  
IOError: failed to write data  

The solution was to disable compression by adding the following lines to hgweb.config

[server]  
preferuncompressed = true  

By default, Mercurial will compress everything before sending it down the pipe. This makes sense if you have a powerful server and a slow network, but the opposite was true for us - Mercurial’s hosted on an old dual-core Windows VM connected to a 1Gb corporate LAN.

[Read More]

Error creating logs directory in Apache Tomcat

java.util.logging.ErrorManager: 4: Unable to create [c:pache-tomcat-7.0.30 -Dcatalina.home=c:pache-tomcat-7.0.30\logs\]

I was getting this error recently, and found that it was caused by having a trailing backslash on my CATALINA_HOME variable.

i.e.
Incorrect:

set CATALINA_HOME=c:pache-tomcat-7.0.30\

Correct:

set CATALINA_HOME=c:pache-tomcat-7.0.30
Tomcat 

Anti-pattern: Re-use through inheritance

When I first started programming in object oriented languages I used inheritance to reduce code duplication. You know the deal - you have two classes that do the same sort of thing so you create an abstract superclass and extract the common code into methods in the superclass. VoilĂ . No more duplicated code.

But I was unwittingly creating an untestable codebase.

I have worked extensively with dependency injection containers over the last five years and have begun to rely on the clean code they facilitate. DI encourages loosely coupled classes and interface abstractions, so code re-use is typically achieved by extracting the common code into its own class and injecting that class as a collaborator.

[Read More]

JUnit categories with Maven

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ junit-categories ---
[INFO] com.craigpardey:junit-categories:jar:1.0-SNAPSHOT
[INFO] +- org.jmock:jmock-junit4:jar:2.6.0-RC2:test
[INFO] |  +- org.jmock:jmock:jar:2.6.0-RC2:test
[INFO] |  |  \- org.hamcrest:hamcrest-library:jar:1.3.RC2:test
[INFO] |  \- junit:junit-dep:jar:4.4:test
[INFO] \- junit:junit:jar:4.10:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.1:test

See how jmock-junit4 depends on junit-dep:4.4, and that it appears before JUnit 4.10? That’s the cause of the error above. You can either exclude each of these conflicting dependencies or you can make sure that the versions of JUnit and/or JUnit-dep appear first in the classpath. The latter is achieved by putting them at the top of the dependency list in your pom.xml (or better yet, the parent pom.xml if you have one).
Here’s the dependency tree after moving the JUnit dependency above the jMock dependency in my pom.xml

[Read More]
JUnit 

Mercurial ignore file for Maven projects

I find it hard to remember all the .hgignore settings for a new Mercurial repository that I need, so here’s a bootstrap version

syntax: glob
.hgignore
*/target/**
*/.settings/**
*/.classpath
*/.project
*.log
*.orig

No stand-up

There was no stand-up this morning and it felt like my day never really started. It was my first day at my new job with CIBC and, even though I knew that the team was not agile before signing up for the gig, I had underestimated how much I depended upon our daily rituals practices at Intelliware. These practices provided a rhythm and cadence to the day that I had taken for granted.

[Read More]
Agile 

Maven Release from Jenkins

I encountered this error while setting up a Jenkins job to automate our Maven release process.

[INFO] EXECUTING: cmd.exe /X /C "hg commit --message "[maven-release-plugin] prepare for next development iteration" c:\jenkins\jobs\Release\workspace\pom.xml"  
[DEBUG] abort: C:\Jenkins\jobs\Release\workspace\pom.xml not under root  
[ERROR] EXECUTION FAILED  
Execution of cmd : commit failed with exit code: -1.  
Working directory was:  
c:\jenkins\jobs\Release\workspace  
Your Hg installation seems to be valid and complete.  
Hg version: 2.0 (OK)  

Our Jenkins box runs on Windows. It turns out the Mercurial (HG) is case- sensitive in a way that hadn’t impacted our project in any way up until this point. Note the subtle differences in the first two log statements:

[Read More]