TaT MavenBuildAllProjects

Auto-build maven2 projects in the correct order

Preface

  • Tested with NetBeans 6.5 pre-release builds, Maven plugin 3.1.3
  • Solution should work with plain Maven2, as well, same as with older NetBeans/maven plugin versions.

Situation

maven2 is quite a powerful tool for managing your application structure, dependencies, build, deployment and a few other things which perfectly integrates with recent releases of NetBeans. Possibly there is just one problem you might stumble upon while dealing with more complex project structures, rooted in the fact that, different to stock, ant-based projects, the tooling so far is not capable of transitively building dependent local maven2 projects. To outline this, consider the following sample project structure:

File:01-project-structure_TaT_MavenBuildAllProjects.jpg

This one, basically, includes two projects:

  • my-application-api
    , as the name suggests, is some imaginary software systems API, including interface definitions, entity classes and the like.
  • my-application-impl
    , possibly same as obvious, provides implementation of the interfaces defined in {-api} and, thus depends upon the my-application-api project (or, in maven2 terminology, artifact).
Having these two projects created anew, you will notice the "red" marking of "my-application-api-1.0-SNAPSHOT.jar" in the "Libraries" section of
my-application-impl
, showing that the .jar file representing this artifact is not yet around in your local maven2 repository (usually to be found in your home folder in {.m2/repository}). Nevertheless, you already may work in both projects, implement classes in my-application-impl and see that everything seems fine, because, having both project opened, NetBeans knows about the code in the my-application-api project:

File:02-impl-class_TaT_MavenBuildAllProjects.jpg


Nevertheless now, trying to get the
my-application-impl
built will inevitably produce an error like this:

File:03-build-error_TaT_MavenBuildAllProjects.jpg

This, after all, is reasonable: Given the maven2 build mechanism, while building a project / artifact maven2 expects its dependencies to be around in the local maven2 repository, which is not the case for
my-application-api
(as so far this project has not yet been built). Getting out of this is rather easy: Invoke right-click -> "Clean and Build" on {my-application-api} and, then, repeat the same for my-application-impl to see the build proceed as you want it to. After that, looking at the project structure of my-application-impl, you'll also see the dependency to my-application-api not marked as red ("missing") anymore:

File:04-api-build-dependencies-there_TaT_MavenBuildAllProjects.jpg


So far an easy solution, having two major drawbacks however:

  • Starting anew, having none of the artifacts in place in your repository, this is pretty easy as they will be marked as missing in projects depending upon them. Having changed code while there are older versions of the same artifacts jar files in your repository makes things a little more uncomfortable here: Even if the code seems right in NetBeans (which works with the source code in the opened maven2 projects), the build is likely to fail because, at build time, maven2 uses the artifacts in .m2/repository and, thus, "old" code compared to the opened project that hasn't been built yet.
  • Adding to this, things start getting considerably ugly as soon as the amount of maven2 projects and dependencies between them does get a little bigger and more complicated - by then you quickly might be into manually rebuilding a lot of projects, hoping to remember the right dependency / rebuild order each and every time, which might not be an easy job to say the very least.


Solution

There are some enhancement requests (like this one) opened in NetBeans issue tracker to provide better IDE / build support for situations like this. So far however, help is at hand using a standard feature provided by maven2, referred to as "multi-modules projects". To make use of this and drastically clean up your build process in situations like outlined above, do the following:

  • Create an empty maven2 artifact, eventually using the "quickstart" archetype in the NetBeans project creation wizard. In the example, this project is named
    my-application-build-helper
    . Take care to create this one in the same folder the other (two) projects have been created before.
  • As soon as project creation has finished, double-click open its
    pom.xml
    , change the content of the {<packaging>} tag from 'jar' to 'pom' and replace the whole <dependencies>... tag with a <modules>... entry. Done so, your POM definition should look more or less like this:

File:05-build-helper-pom_TaT_MavenBuildAllProjects.jpg

  • Switch to the "File" view of your NetBeans IDE, browse to the
    my-application-build-helper
    project folder and delete its complete {src} folder. The only thing that should be left in there is the pom.xml. Though this is not strictly required, it will keep you from accidentially adding code to the build helper which possibly shouldn't be there. After doing so, your my-application-build-helper project structure should look like this:

File:06-build-helper-structure_TaT_MavenBuildAllProjects.jpg

  • Editing the build helpers
    pom.xml
    , add {<module>} entries for each project to be built. Doing so, it suffices having all the projects to be included listed as modules in this POM; while building the "build helper", maven2 will take care of figuring out the right order to build them. Note that module references are relative to the current projects POM definition so, given all the projects live in the same folder, include a "../" to every module. Ending this, your POM should look like this:

File:07-build-helper-modules_TaT_MavenBuildAllProjects.jpg

  • By then, right-click the build helper and choose "Clean and build". After maven has done its work, you will see all the projects have been built, as well as the build order that has been applied:

File:08-build-helper-build-outcome_TaT_MavenBuildAllProjects.jpg

Background and conclusion

From a maven2 point of view, basically you do make your project organization a little more strict: Where you used to have a set of standalone modules along with dependencies between them, using the "build helper" actually is about introducing a "parent" POM to unify several maven2 artifacts into one multi-module project.

Though this solution does take some manual work initially, it will save you a lot of time rebuilding more complex maven2 project structures, and, later on, it also may ease deployment of many artifacts to, in example, an internal archiva artifact repository. Plus, as this is mainly a solution based upon maven2 features, it will also work if you ever have to manually rebuild these projects without having a NetBeans IDE at hand (i.e. working on a headless server via ssh...). However the drawback this solution is suffering from definitely is that, using the build helper to contain a whole project structure (consisting of a bunch of modules), everything gets rebuilt all the time - regardless of whether projects have or haven't changed, same as regardless of whether or not projects listed in the build-helper pom actually directly depend upon those who have changed. But compared to the effort of manually rebuilding the required dependency path, maybe this is something one could live with...


References


MKLEINT: An alternate approach could be to use the Maven Reactor plugin, it's not released yet AFAIK, but it shall be allow to build

  • all projects that this project depends on (from a given set)
  • all projects that depend on this project (again from a given set)
Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo