Maven parent pom vs modules pom

There seem to be several ways to structure parent poms in a multiproject build and I wondering if anyone had any thoughts on what the advantages / drawbacks are in each way.

The simplest method of having a parent pom would be putting it in the root of a project ie

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

where the pom.xml is both the parent project as well as describes the -core -api and -app modules

The next method is to separate out the parent into its own subdirectory as in

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

Where the parent pom still contains the modules but they're relative, eg ../myproject-core

Finally, there's the option where the module definition and the parent are separated as in

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

Where the parent pom contains any "shared" configuration (dependencyManagement, properties etc.) and the myproject/pom.xml contains the list of modules.

The intention is to be scalable to a large scale build so should be scalable to a large number of projects and artifacts.

A few bonus questions:

  • Where is the best place to define the various shared configuration as in source control, deployment directories, common plugins etc. (I'm assuming the parent but I've often been bitten by this and they've ended up in each project rather than a common one).
  • How do the maven-release plugin, hudson and nexus deal with how you set up your multi-projects (possibly a giant question, it's more if anyone has been caught out when by how a multi-project build has been set up)?
  • Edit: Each of the sub projects have their own pom.xml, I've left it out to keep it terse.


    In my opinion, to answer this question, you need to think in terms of project life cycle and version control. In other words, does the parent pom have its own life cycle ie can it be released separately of the other modules or not?

    If the answer is yes (and this is the case of most projects that have been mentioned in the question or in comments), then the parent pom needs his own module from a VCS and from a Maven point of view and you'll end up with something like this at the VCS level:

    root
    |-- parent-pom
    |   |-- branches
    |   |-- tags
    |   `-- trunk
    |       `-- pom.xml
    `-- projectA
        |-- branches
        |-- tags
        `-- trunk
            |-- module1
            |   `-- pom.xml
            |-- moduleN
            |   `-- pom.xml
            `-- pom.xml
    

    This makes the checkout a bit painful and a common way to deal with that is to use svn:externals . For example, add a trunks directory:

    root
    |-- parent-pom
    |   |-- branches
    |   |-- tags
    |   `-- trunk
    |       `-- pom.xml
    |-- projectA
    |   |-- branches
    |   |-- tags
    |   `-- trunk
    |       |-- module1
    |       |   `-- pom.xml
    |       |-- moduleN
    |       |   `-- pom.xml
    |       `-- pom.xml
    `-- trunks
    

    With the following externals definition:

    parent-pom http://host/svn/parent-pom/trunk
    projectA http://host/svn/projectA/trunk
    

    A checkout of trunks would then result in the following local structure (pattern #2):

    root/
      parent-pom/
        pom.xml
      projectA/
    

    Optionally, you can even add a pom.xml in the trunks directory:

    root
    |-- parent-pom
    |   |-- branches
    |   |-- tags
    |   `-- trunk
    |       `-- pom.xml
    |-- projectA
    |   |-- branches
    |   |-- tags
    |   `-- trunk
    |       |-- module1
    |       |   `-- pom.xml
    |       |-- moduleN
    |       |   `-- pom.xml
    |       `-- pom.xml
    `-- trunks
        `-- pom.xml
    

    This pom.xml is a kind of "fake" pom: it is never released, it doesn't contain a real version since this file is never released, it only contains a list of modules. With this file, a checkout would result in this structure (pattern #3):

    root/
      parent-pom/
        pom.xml
      projectA/
      pom.xml
    

    This "hack" allows to launch of a reactor build from the root after a checkout and make things even more handy. Actually, this is how I like to setup maven projects and a VCS repository for large builds : it just works, it scales well, it gives all the flexibility you may need.

    If the answer is no (back to the initial question), then I think you can live with pattern #1 (do the simplest thing that could possibly work).

    Now, about the bonus questions:

  • Where is the best place to define the various shared configuration as in source control, deployment directories, common plugins etc. (I'm assuming the parent but I've often been bitten by this and they've ended up in each project rather than a common one).
  • Honestly, I don't know how to not give a general answer here (like "use the level at which you think it makes sense to mutualize things"). And anyway, child poms can always override inherited settings.

  • How do the maven-release plugin, hudson and nexus deal with how you set up your multi-projects (possibly a giant question, it's more if anyone has been caught out when by how a multi-project build has been set up)?
  • The setup I use works well, nothing particular to mention.

    Actually, I wonder how the maven-release-plugin deals with pattern #1 (especially with the <parent> section since you can't have SNAPSHOT dependencies at release time). This sounds like a chicken or egg problem but I just can't remember if it works and was too lazy to test it.


    From my experience and Maven best practices there are two kinds of "parent poms"

  • "company" parent pom - this pom contains your company specific information and configuration that inherit every pom and doesn't need to be copied. These informations are:

  • repositories
  • distribution managment sections
  • common plugins configurations (like maven-compiler-plugin source and target versions)
  • organization, developers, etc
  • Preparing this parent pom need to be done with caution, because all your company poms will inherit from it, so this pom have to be mature and stable (releasing a version of parent pom should not affect to release all your company projects!)

  • second kind of parent pom is a multimodule parent. I prefer your first solution - this is a default maven convention for multi module projects, very often represents VCS code structure
  • The intention is to be scalable to a large scale build so should be scalable to a large number of projects and artifacts.

    Mutliprojects have structure of trees - so you aren't arrown down to one level of parent pom. Try to find a suitable project struture for your needs - a classic exmample is how to disrtibute mutimodule projects

    distibution/
    documentation/
    myproject/
      myproject-core/
      myproject-api/
      myproject-app/
      pom.xml
    pom.xml
    

    A few bonus questions:

  • Where is the best place to define the various shared configuration as in source control, deployment directories, common plugins etc. (I'm assuming the parent but I've often been bitten by this and they've ended up in each project rather than a common one).
  • This configuration has to be wisely splitted into a "company" parent pom and project parent pom(s). Things related to all you project go to "company" parent and this related to current project go to project one's.

  • How do the maven-release plugin, hudson and nexus deal with how you set up your multi-projects (possibly a giant question, it's more if anyone has been caught out when by how a multi-project build has been set up)?
  • Company parent pom have to be released first. For multiprojects standard rules applies. CI server need to know all to build the project correctly.


  • An independent parent is the best practice for sharing configuration and options across otherwise uncoupled components. Apache has a parent pom project to share legal notices and some common packaging options.

  • If your top-level project has real work in it, such as aggregating javadoc or packaging a release, then you will have conflicts between the settings needed to do that work and the settings you want to share out via parent. A parent-only project avoids that.

  • A common pattern (ignoring #1 for the moment) is have the projects-with-code use a parent project as their parent, and have it use the top-level as a parent. This allows core things to be shared by all, but avoids the problem described in #2.

  • The site plugin will get very confused if the parent structure is not the same as the directory structure. If you want to build an aggregate site, you'll need to do some fiddling to get around this.

  • Apache CXF is an example the pattern in #2.

  • 链接地址: http://www.djcxy.com/p/29698.html

    上一篇: 无论如何排除从父POM继承的工件?

    下一篇: Maven家长pom vs模块pom