views:

339

answers:

2

For educational purposes I have set up a project layout like so (flat in order to suite eclipse better):

-product
 |
 |-parent
 |-core
 |-opt
 |-all

Parent contains an aggregate project with core, opt and all. Core implements the mandatory part of the application. Opt is an optional part. All is supposed to combine core with opt, and has these two modules listed as dependencies.

I am now trying to make the following artifacts:

  1. product-core.jar
  2. product-core-src.jar
  3. product-core-with-dependencies.jar
  4. product-opt.jar
  5. product-opt-src.jar
  6. product-opt-with-dependencies.jar
  7. product-all.jar
  8. product-all-src.jar
  9. product-all-with-dependencies.jar

Most of them are fairly straightforward to produce. I do have some problem with the aggregating artifacts though. I have managed to make the product-all-src.jar with a custom assembly descriptor in the 'all' module which downloads the sources for all non-transitive deps, and this works fine. This technique also allows me to make the product-all-with-dependencies.jar.

I however recently found out that you can use the source:aggregate goal in the source plugin to aggregate sources of the entire aggregate project. This is also true for the javadoc plugin, which also aggregates through the usage of the parent project.

So I am torn between my 'all' module approach and ditching the 'all' module and just use the 'parent' module for all aggregation. It feels unclean to have some aggregate artifacts produced in 'parent', and others produced in 'all'. Is there a way of making an 'product-all' jar in the parent project, or to aggregate javadoc in the 'all' project? Or should I just keep both?

Thanks

A: 

I'd suggest just keeping the assembly descriptor from "all", move it to parent/ and change parent/pom.xml accordingly, and then create that assembly by doing something like mvn -f parent/pom.xml assembly:assembly. In other words, yeah, remove the redundant project for "all" since it is just duplicating what "parent" is already doing.

On a side note, "parent" seems like a poor naming choice for that project if it's an aggregate project and not just a parent pom.xml.

[Edit]

Although a much larger project, perhaps a project that is laid out how you are envisioning is the apache camel project. Check it out here: http://camel.apache.org/source.html . There is a parent/ module that handles all of the for everything else, and a separate module for producing the actual build distributions in apache-camel/ (with assembly descriptors in apache-camel/src//main/descriptors). Perhaps that will be more of a help.

whaley
are you suggesting that I should have one parent, with only a parent pom, and one 'aggregate', which builds the complete product? Should you put 'dependencyManagement' in parent or in aggregate then? Can you suggest a good example project?
disown
Essentially yes. If your "aggregate" isn't doing anything than calling an assembly descriptor though there is no need to have it in a separate module. That can just live with the top level pom (probably not with the parent, as I first suggested).<dependencyManagement> and <pluginManagement> should live with the parent pom.If you have lots of complex aggregation (say... an individual build for Windows, Linux, and OSX) then those aggregates should be in inidividual modules. In your case it sounded like just a simply assembly would do.
whaley
Sorry for dragging this one out, but how do you make a complete jar for an aggregate project? I can't seem to figure out how to do this without creating an 'all' project.
disown
If I understand you correctly, you make the parent project of type 'pom', and the win, linux and osx aggregate projects of type 'jar'. But how do I make the win jar, containing all the binaries of its child modules?
disown
Like in this article - a separate dist project is set up, assembly is not done from the aggregate project: http://rombertw.wordpress.com/2010/05/14/maven-recipe-building-an-aggregate-jar/
disown
+1  A: 

Flattened trees are not often used anymore. This was done several years ago to deal with how Eclipse handled projects and the lack of good Maven and Eclipse integration. If you use m2eclipse to import Maven projects into Eclipse, you won't have any problems with a maven-typical nested tree.

As far as what is a good example of how to structure a Maven build? The Maven project source itself. It has all the pieces you desire, including the final assembly that packages up the bundles.

The typical nested structure has a top down hierarchy where the parent is doing the aggregation of the modules below it, and the children are inheriting values from the parent. Although these can and sometimes are separate, this is not the norm.

Brian Fox
Thanks for the tip. I just had a look at it and it seems like the maven source follows the general layout that I suggested, however without flattening the tree as you pointed out. The final assembly is IMO not very clean, it just does a regex grep for all source files in the '../' directory, not easy if you want sources from 3:rd party dependencies etc. Also not in line with how the javadoc aggregator work (through the parent project). It seems like the functionality I would like is missing, I'll try to write up an alternative approach here when I've experimented some. Thanks for the pointer.
disown
BTW, the src assembly can be found at http://svn.apache.org/repos/asf/maven/maven-3/trunk/apache-maven/src/main/assembly/src.xml
disown