Treat your App.config like a global variable

I remember looking at a few codebases in C# and it surprised me how many people encapsulate some of their system well, yet treat their application configuration as a different thing. Many times I’ve seen code that looks like: ConfigurationSettings.AppSettings["DatabaseConnectionString"]; alongside the thing that is using it. In fact, I often see this code repeated in various parts of the system wherever anyone needs to draw on application configuration.

Global variables are bad
Most good programmers seem to realise that most global variables are bad, yet this is exactly what I think accessing the application configuration is like. If you want to change the way your configuration is loaded (i.e. programmatically or from a database) think of how many places you now need to change it, let alone how it effects the order in which you instantiate objects.

My advice: Separate the use of configuration from where it declared
I try to follow the pattern isolating the configuration into a single class depending on the access method, such as:

  • DatabaseBackedConfiguration
  • FileBackedConfiguration
  • DefaultInMemoryBackedConfiguration

Each of these classes them implement several roles depending on what configuration they might provide such as:

  • HibernateConfiguration
  • ApplicationConfiguration
  • ArchivingConfiguration

Having smaller roles makes it clearer what sort of configuration is really needed for a particular consumer, and it allows me to change the decision about how that configuration is now provided to it. It enables me to do things like specify different environment configurations and do so in the method that I prefer.

Defensive programming depends on context

I remember stepping into a heated discussion with two developers who just couldn’t agree whether or not they should be writing their code defensively. One of them argued they should always be checking for null, checking for illegal input and throw appropriate exceptions before doing anything with it. The other argued that they should not because of the amount of code that would add to every single method. I think I understood where they were both coming from and suggested that they were both correct though under different circumstances. One of them asked me to explain, and considering I see this argument resurfacing again here and here, I thought I’d post my thoughts.

Defensive Programming

Scenario A: Dealing with those outside of your circle of trust
Let’s say you’re working in Team A, developing an API for the greater public. It might be as big as a core platform development API, or an opensource library. Either way, it’s not possible to learn how everyone is going to use your API and not enough to simply document it because some people will not read all the documentation. Programming defensively helps consumers understand how your code was meant to called because there is no single way you can ensure your clients have the same understanding, regardless of the amount of documentation you put together. They lie outside of your sphere of influence. The longer the release cycles, the greater the risk someone might use your API in a way you hadn’t intended. This is the situation the authors of the .Net Framework Guideline worked under and as such you’ll see they’re emphasis on defensive programming. You don’t always have to do it in this situation, you’re just more likely to.

Scenario B: Dealing with those inside your sphere of influence
You might be working closely with another team, either in your organisation or in another one, writing an API for them to consume. Do you write your code defensively? I think it depends on how much influence you have. If you have enough influence that both parties understand the contract well, and your release cycles are reasonably fast, you may not have to. If you have long release cycles, or your relationship with the other team is more like the general public (you have no idea how they’re going to use your API), you may choose to program more defensively to provide faster feedback for your clients. I try to use this as the last resort when I’m in this particular situation.

Scenario C: Inside your own team
I rarely find good reasons to program defensively for code that I will ultimately write. It doesn’t really make sense for me to add in additional lines of code where I can easily test all the execution paths of the final code.

Conclusion
This advice is in constant practice. Even when you’re working under Scenario A, it’s only your external APIs that you are probably interested in programming defensively. Delegating to all other private or internal members will often be in the context of Scenario B or Scenario C. Remember the rule that ‘Context is King’, so ensure everyone understands that context before jumping to a particular conclusion about what you should or should not be programming defensively.

Retrospectives: Making Issues More Visible

Magnifying GlassI remember reading about the Cause, Made Visible and Not Related story on Esther Derby’s blog a while back. My biggest takeaway was that retrospectives aren’t normally the Cause of issues, instead creating Visibility into the issues already present. People constantly surprise me when they say that don’t like retrospectives because it doesn’t fix their issues. Guess what? Simply holding a retrospective won’t magically fix all your issues because it isn’t the Cause of them. Yet how do you go about fixing your issues if you don’t take the time to identify what issues you have, what impact they’re having and how you’re going to fix the true Cause?

Image taken from Dr Pat’s Flickr photostream under the Creative Commons licence.

Maven FAQ

Maven only has 20 FAQs on its page here. I’ve been working with it on a project recently, and frankly I had plenty more than 20 to ask. Here’s my list of a few things that I hope will help people when they’re searching for answers not described well in the Maven documentation.

How do I get a plain file (*.txt) included into my deployment file (i.e. jar, war, ear)?
Maven’s default file structure looks like ${projectBase}/src/main. The compile target looks for production code under ${projectBase}/src/main/java. It looks for other files to include with your production deployment in ${projectBase}/src/main/resources. Adding your file to that directory will automatically include them in your deployment file.

When Maven downloads its dependencies, where does it store those files on a windows machine?
Look for files under C:\Documents and Settings\${userName}\.m2\repository.

Why doesn’t a feature from JDK5 or 6 work?
By default, Maven compiles against JDK1.3. Set the source and target JDK where you have your compile target:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
    </configuration>
</plugin>

How can I create a single deployment file with all dependent libraries merged?
Instead of using the maven-jar-plugin plugin, use the maven-assembly-plugin. Here’s an example

<plugin>
     <artifactId>maven-assembly-plugin</artifactId>
     <configuration>
          <descriptorRefs>
               <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
               <manifest>
                    <mainClass>com.thekua.spikes.App</mainClass>
               </manifest>
          </archive>
     </configuration>
     <executions>
          <execution>
               <id>make-assembly</id>
               <phase>package</phase>
               <goals>
                    <goal>attached</goal>
               </goals>
          </execution>
     </executions>
</plugin>

Office 2007 Woes: Insert New Worksheet

Excel 2007 is quite a horrible experience. Someone recently told me a story where apparently, Micro$oft said that it’s easier for new users to learn, yet would take three weeks of re-training for existing office users. Shame I fall into the latter crowd and not the former. Read on if you are wondering where your worksheets went and want to insert a new worksheet. (more…)

Unhelpful Error Messages in Maven

What’s wrong with this: “Cannot execute mojo: resources. It requires a project with an existing pom.xml, but the build is not using one.”

How about? What are you talking mojo to me for? What is going wrong and how do I fix it?

Perhaps something like this would be a better error message: “Maven is looking for the pom.xml file and cannot find it. Maven assumes this file is in the directory you are running it from. If you are running Maven in a different directory, perhaps you might want to use the –file switch.”