Protect Your Resources
Class files are usually loaded from the classpath. Non-class files (resources) can be loaded from the classpath as well, using the various
methods. If you want to keep these resources from getting wiped out every time you invoke the
goal, you need to store resources outside of the classes directory and copy them into the classes directory as part of the build process. Maven has a goal for this purpose called
. It doesn't jar anything, it just copies resources to the
directory. Maven automatically calls the
goal when you run the
First, you need to tell Maven where your resource files are:
- Add the
resources element, as shown below, to
- Place a resource file, say
- Run the
jar goal, which indirectly runs the
Look in the
target/classes folder. You should see that Maven copied
Creating Goals and Plug-ins
Like Ant, Maven allows you to create your own goals. You can utilize Maven goals at varying levels:
- Use an existing goal as is.
- Extend an existing goal.
- Create your own project-level goal.
- Create your own cross-project goal by creating a Maven plug-in.
I discuss each of these in the following sections.
Project-specific goals are defined in a file called
maven.xml, which is roughly analogous to Ant's
build.xml. Here are the steps to create a project-specific goal in Maven:
- Create a file called
maven.xml in your project root:
- Add the following XML snippet:
- Invoke the goal:
As you can see, with
maven.xml, Maven can act just like Ant. (By the way,
mkdir is an Ant task.) Maven can execute any Ant task, and it also supports most of the JSTL tags, which provide basic logic and looping functionality. For example, if you wanted to create a goal that makes five directories, you could use the following:
<c:forEach begin="1" end="5" indexVar="i">
maven.xml file is actually a Jelly Script. Jelly is a general-purpose, XML-based scripting language. Maven uses it, but it's not specific to Maven. (See the sidebar "Jelly: Executable XML" for more information.)
Extending a Goal
You can extend an existing goal in a project-specific way by defining a
preGoal and/or a
postGoal element in
maven.xml. For example, if you're happy with Maven's built-in
clean goal but you would also like Maven to clear your application server's temporary cache, you could extend
clean with a
postGoal. My application server, Caucho Resin, uses a directory called
WEB-INF/work for it's temporary files. Try adding the following block of code to
<echo>Deleted Resin work directory</echo>
Then rerun the
Cross-project Goals (Plug-ins)
Maven allows you to create generic, reusable goals, which in my opinion are what make Maven so useful. By comparison, Ant supports reusable tasks, but not reusable targets. To create a reusable goal, you need to create a Maven plug-in.
As an example, I use Solarmetric's Kodo, a JDO compliant object/relational mapping tool. JDO is a great technology but it adds an extra step to the build process. Specifically, you have to run a separate task that adds persistence functionality to your class files (JDO refers to this as byte-code enhancement). Luckily, you can call the byte-code enhancer from a Maven goal. And since I use Kodo in multiple projects, it's a great candidate for a cross-project goal, or in other words, a plug-in.
For the sake of simplicity, start with a slightly less ambitious "hello world" plug-in. Take the following steps to create a minimal Maven plug-in:
- Create a directory for the plug-in:
- Create the
<echo>Hello Maven Plug-in!</echo>
- Create a minimal
project.xml file inside the plug-in's folder:
project.xml file obviously adds no value to your plug-in, and logically you don't need it. But Maven will return an error message if you don't provide it. More sophisticated plug-ins will make use of this file to extend the POM with plug-in-specific settings.
- Invoke the new plug-in:
You've completed your first plug-in!
More Than a Build Tool
Although I've described and primarily used Maven as a build tool, it is actually more than just that. The Maven Web site describes Maven as "a Java project-management and project-comprehension tool." For example, the POM (
project.xml) has tags to specify the developers' names, the developers' e-mail addresses, the project inception date, etc. Goals such as
site:generate will then use that information to auto-generate a project Web site to document your project.
Remember, the power of Maven is in its plug-ins. So spend some time exploring the many plug-ins and goals that it provides. For if you have to maintain multiple, large build scripts and you're tired of copy-and-paste reuse, Maven and its long list of plug-ins will make your life easier.
Dave Ford thanks Jason van Zyl (Maven's architect) and his associates, Ron Hitchens, Dave Solum, John Sheehan, and Jordan Fisher, for contributing valuable feedback for this article.