Thursday, July 12, 2012

Use ${basedir} in Maven.. ALWAYS!

If you come across different outcomes in your maven build depending on whether you invoked the maven command inside project's directory or its parent directory, you are doing it wrong somewhere. The build should be consistent. If that module is part of a big multi-module project, project should behave the same always even it's built in the command line or as a part of a build scheduled in a continuous integration server.

For example if you refer to a directory like <directory>target/site</directory> it will look for the target directory at the location the command was executed. This will make things inconsistent depending on whether you invoked it inside the sub-module or the parent project. But referring to it like <directory>${basedir}/target/site</directory> will make sure the target directory will always be searched in one location, the directory where the pom.xml lies. For some reason, if you want to point to the directory from which the maven command was executed use ${user.dir}

For a full list of Maven properties read Maven Properties Guide or this chapter on Sonatype's book, 'Maven: The Complete Reference'.

TL;DR : Remember ${basedir} always represents the directory containing the pom.xml


  1. Just a quick note: basedir is deprecated now. Use ${project.basedir} instead.

  2. I spent hours last night trying to figure out if there was a bug in one of my maven plugins. Finally hacked my pom with a profile to get the correct code generation: but that was wholly unsatisfying. Couldn't sleep, kept chewing over this weird behavior of it works when I run here, but not in the's almost like "maven can't find the resource" depending on where I'm running. Came into work this morning and googled "maven basedir" and your post came up. Wish I'd had the presence of mind to calm down and think about the behavior, rather than thinking there was a bug in the plugin. Absolutely loved your opening paragraph too: "'re doing it wrong." For real. :-)