Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Apache Maven Simplifies the Java Build Process—Even More Than Ant : Page 4

Apache Maven's reuse mechanisms simplify the build process and generally improve upon the popular Ant tool's functionality. In fact, developer and Java technology trainer Dave Ford believes Maven could very well replace Ant as your preferred Java build tool.


advertisement
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 getResource methods. If you want to keep these resources from getting wiped out every time you invoke the clean 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 jar-resources. It doesn't jar anything, it just copies resources to the target/classes directory. Maven automatically calls the jar-resources goal when you run the jar goal.

First, you need to tell Maven where your resource files are:

  1. Add the resources element, as shown below, to project.xml:

    ... </unitTest> <resources> <resource> <directory> ${basedir}/src/conf </directory> </resource> </resources> </build> ...

  2. Place a resource file, say box.properties, in <project_home>/src/conf.
  3. Run the jar goal, which indirectly runs the jar-resources goal:


    maven jar

Look in the target/classes folder. You should see that Maven copied box.properties from src/conf to target/classes.

Creating Goals and Plug-ins
Like Ant, Maven allows you to create your own goals. You can utilize Maven goals at varying levels:

  1. Use an existing goal as is.
  2. Extend an existing goal.
  3. Create your own project-level goal.
  4. Create your own cross-project goal by creating a Maven plug-in.

I discuss each of these in the following sections.

Project-specific Goals
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:

  1. Create a file called maven.xml in your project root:

    c:\daven\maven.xml
  2. Add the following XML snippet:

    <project> <goal name="myGoal-1"> <mkdir dir="c:\myFolder"/> <echo>Hello Maven</echo> </goal> </project>

  3. Invoke the goal:

    maven myGoal-1

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:

<goal name="myGoal-2"> <c:forEach begin="1" end="5" indexVar="i"> <mkdir dir="c:\myFolder${i}"/> <echo>${i}</echo> </c:forEach> </goal>

The 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 maven.xml:

<postGoal name="clean:clean"> <delete dir="${basedir}/WEB-INF/work"/> <echo>Deleted Resin work directory</echo> </postGoal>

Then rerun the clean goal:

maven clean

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:

  1. Create a directory for the plug-in:

    <USER_HOME>\.maven\plugins\maven-hello-plugin-1.0


  2. Create the plugin.jelly file:

    File name:

    <USER_HOME>\.maven\plugins\maven-hello-plugin-1.0\plugin.jelly

    Content:

    <project> <goal name="hello"> <echo>Hello Maven Plug-in!</echo> </goal> </project>



  3. Create a minimal project.xml file inside the plug-in's folder:

    File name:

    <USER_HOME>\.maven\plugins\maven-hello-plugin-1.0\project.xml

    Content:

    <project></project>

    This 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.
  4. Invoke the new plug-in:

    maven hello

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.

Acknowledgements
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.



Dave Ford is a developer and lead trainer for Smart Soft, a developer training company that provides hands-on workshops in Java- and J2EE-related topics. His newest workshops include Java Data Objects, J2EE patterns, and Apache Maven. to e-mail Dave.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap