tags:

views:

654

answers:

4

I'm a bit of a Maven newb, and I'm trying to setup a maven project that builds several child projects, but still allows someone to just grab one of the child projects and build it independently without the parent.

parentfolder
  ->pom.xml
  ->project1
    ->pom.xml
    ->src
  ->project2
    ->pom.xml
    ->src
  ->project3
    ->pom.xml
    ->src

Basically I want someone to be able to checkout parentfolder and do mvn compile to build all the projects, and also for someone to be able to checkout just project1 and do mvn compile to build just it.

I've tried declaring the sub-projects as modules in the top-level pom.xml,

<modules>
  <module>project1</module>
  <module>project2</module>
  <module>project3</module>
</modules>

But that seems to require that the parent pom.xml info is declared in the children. This makes the child projects dependent on the parent pom.xml being present, which is what I wanted to avoid.

A: 

The parent pom and its version does have to be declared in the children.

If your projects have a parent declared, it must be available either in the build so one of the modules must be the parent pom, or in a repository. You seem to be saying you want someone to checkout a project that depends on a parent, but not have access to the parent and still be able to build the project which is like trying to build a project without its dependencies.

You're options to make the parent pom available are:

  • Set up a public maven repository, deploy the parent pom to it, and put the repository information in the child poms.
  • You can tell maven to look for the parent pom on a relative path before it checks repositories (this is to help you when you have local changes to the parent pom, not yet deployed). So you could concievably do an svn:external or its equivalent in your child project to your parent pom.
Scott Ray
A: 

You have to take care of the differences between the parent-child relation and the aggregation concept in Maven2. They are not the same principle, even if they are really often used at the same time.

PARENT

The first concept is that a project declares in his pom.xml a parent:

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>foo</groupId>
        <artifactId>bar</artifactId>
        <version>42</version>
    </parent>
    ...

In this case, in order to build this component, the parent project must be found in the local repository. This is your case here.

The interest of the parent concept in Maven 2 is to inherit properties, dependencies, configuration. This is the place where you will put all the common information of the children projects.

This is the exact same concept of the extends in Java language.

AGGREGATION

In this case, you have a project that aggregates several sub modules by specifying their names in module nodes:

<modules>
    <module>commons</module>
    <module>client</module>
    <module>server</module>
    ...
</modules>

This means that every command that you will run on this root project will be executed on each module (the order is defined by the Maven 2 Reactor). For example, if you run mvn clean install on the root project, Maven 2 will run this command on the root project, then on project commons, then on client and finally on server.

In this concept, you are able to compile one project without compiling any other one project (except if there are inter-dependencies of course).

Here is a schema that shows the two different concepts:

alt text

You have a more detailed explanations on these two concepts in the Maven : The Definitive Guide, here.

romaintaz
+1  A: 

The sub-projects are only dependent on the parent if they use the <parent> tag (maven inheritance). You are not required to use the <parent> tag in submodules. However, if you want your modules to inherit common elements from the parent pom, then you have to use maven inheritance.

Strictly speaking, if you are using inheritance and want to build only a sub-project, then the parent pom.xml doesn't have to be present in the parent directory; as long as maven can find the parent pom in a local or remote repository, then it will build. In practice, if there are changes going on in your parent pom, you'll have to work out how to get your team members to keep up to date with the parent pom.

Ken Liu
A: 

It seems to me that the problem is that Maven is overloading the parent tag. Maven docs keep telling me that Inheritance and Aggregation are two different things, yet both use the same tag to achieve their function. This does militate against the scenario that the original poster is asking. One may want to

  1. inherit certain settings from a common parent, yet
  2. have two builds of different applications sharing a common component.

Thus we have two different understandings of the parent relationship here. First, the "parent" contributing the settings for each module and second, the "parent" whose build builds the child. Since there are two of the latter, this breaks down. The two ideas of parentage get in each other's way.